【问题标题】:DownloadFIleCompleted and DownloadProgressChanged not firing in a multithread win forms applicationDownloadFIleCompleted 和 DownloadProgressChanged 未在多线程 win 表单应用程序中触发
【发布时间】:2012-09-03 14:09:11
【问题描述】:

我在多线程应用程序(DownloadFileCompletedDownloadProgressChanged)中使用WebClient 事件时遇到问题。 我有创建计时器的主要方法。每隔一段时间,我将创建一个线程,如果满足某个条件,它将弹出另一个窗体 (DownloaderForm)。

void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e) {
    var thread = new Thread(SilentCheckingUpdate) {
        Name = "Update Checker",
    };
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

SilentChekingUpdate 方法检查更新。

bool found = _updater.UpdateRequired(currentConfig, out latestVersion);

if (found)
{
    _updater.ShowUpdateUI(latestVersion); 
}

如果找到,它会从 win forms 类 Updater 调用另一个方法,该方法从 Downloader 调用 StartDownload。

public void ShowUpdateUI(Item currentItem)
{
    var downloader = new Downloader();
    downloader.StartDownload();
}

下载器包含一个 WebBrowserControl。我做了一个调用 DownloadFileAsync 的方法。

public void StartDownload()
{          
    // start async download
    var client = new WebClient();

    client.DownloadProgressChanged += ClientDownloadProgressChanged;
    client.DownloadFileCompleted += ClientDownloadFileCompleted;
    var url = new Uri(_item.DownloadLink);

    client.DownloadFileAsync(url, _tempName);
}

如果我从表单线程调用 StartDownload 函数,一切正常并且会触发事件。当我使用来自 TimerElapsed 的 StartDownload 工作线程时,DownloadFileAsync 的事件不再被触发。

你能帮帮我吗?

谢谢!

【问题讨论】:

  • 当您不提供显示问题的代码时,很难判断可能出现的问题。您说您在 TimerElapsed 的工作线程中的 StartDownload 有问题,但您没有提供从 TimerElapsed 中创建的线程调用 StartDownload 的代码。
  • 我编辑了包含更多信息的帖子。谢谢你的时间,彼得!

标签: c# winforms multithreading webclient


【解决方案1】:

目前尚不清楚您为什么要启动一个基本上只是调用DownloadFileAsync 的线程——它会异步下载文件。如果DownloadFileAsync 是异步的,则没有太多理由启动另一个线程来调用它。

我想我会考虑的是,您在 StartDownload 方法中创建了一个本地 client 对象。这几乎立即让client 超出范围并可能让GC 收集它。如果发生这种情况,可能会导致问题。 也许client 设为会员字段可能会有所帮助;但是,这是一个猜测。

您还没有提供“有效*”的代码,所以很难说为什么会有差异。

【讨论】:

  • 我启动了一个线程,因为我从 WebBrowser 控件中得到了一个错误,例如:“ActiveX 控件 '8856f961-340a-11d0-a96b-00c04fd705a2' 不能被实例化,因为当前线程不在一个单一的 -螺纹公寓。”
  • 如果您想在表单上使用 ActiveX 控件,您的主线程必须是 STA。创建 Windows 窗体应用程序时,主线程默认为 STA(Program.Main 上的 STAThread)。如果你改变了它,这就是你会得到那个错误的原因。如果您没有更改它,那么您已经创建了另一个调用 WebBrowser 的线程。
  • WebBrowser 只能在 STA 线程上使用,并且只能在具有消息泵的线程上使用。即一个 UI 线程。
  • 你可能是对的。计时器对象可能正在使用另一个线程?
  • 是的,System.Timers.Timer 使用另一个线程。如果您想对 Tick 处理程序中的任何控件执行任何操作,您应该使用 System.Forms.Timer
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
相关资源
最近更新 更多