从不同的对象/类更新GUI上的进度条

本文关键字:GUI 更新 对象 | 更新日期: 2023-09-27 18:05:43

我有一个管理从特定资源下载文件的类。类在GUI线程中实例化。举例来说,这个类被称为MP3Download

MP3Downloader中,我有一个叫做DownloadFile的方法:

public async Task DownloadFIle(string url, string path)
{
    using (WebClient client = new WebClient())
    {
            client.DownloadProgressChanged += (s, e) =>
            {
                Console.WriteLine("Changed");
            };
            try
            {
                await client.DownloadFileTaskAsync(url, path);
            } catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

}

我在GUI上有一个进度条。我想通过某种方式能够将下载的进度报告回进度条。

我是否必须在MP3Downloader类中创建一个事件并从GUI订阅该事件?当DownloadProgressChanged被触发时,我将发送者和事件参数传递给我的自定义事件?

我不想把进度条和MP3Downloader类结合在一起。

从不同的对象/类更新GUI上的进度条

基于任务的异步模式规定了适当的进度过程。如果你只是对百分比感兴趣,这将是:

public async Task DownloadFIle(string url, string path, IProgress<int> progress = null)
{
  using (WebClient client = new WebClient())
  {
    client.DownloadProgressChanged += (s, e) =>
    {
      if (progress != null)
        progress.Report(e.ProgressPercentage);
    };
    await client.DownloadFileTaskAsync(url, path);
  }
}

消费代码可以使用内置的Progress<T>类来响应进度更新。正确的线程封送是由Progress<T>类为您处理的。

"我不想把进度条和MP3Downloader类结合起来"

是啊,那可不酷。在视图层上声明一个接口,然后通过实现(注入依赖项,使用IoC容器)对控制器进行调用,然后MP3Downloader类可以有一个线程,该线程将继续发布有关下载进度的数据到GUI。这只是一个实现,如果你想重用GUI,你只需要携带界面,也就是高内聚性。松散耦合。