【问题标题】:Cross-threading issue, BackgroundWorker and ReportProgress跨线程问题,BackgroundWorker 和 ReportProgress
【发布时间】:2012-05-03 22:46:47
【问题描述】:

我有一个 [STAThread] main,其中包含以下内容:

try
{
    // Start the port enumerator.

    Enumerator enumerator = new Enumerator();

    // Display the main window and start everything going.

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new TopViewForm(ref enumerator));
}
catch (Exception)
{
}

枚举器对象本身包含一个后台工作线程。后台工作是这样初始化的:

MyBackgroundWorker = new BackgroundWorker();
MyBackgroundWorker.WorkerSupportsCancellation = true;
MyBackgroundWorker.WorkerReportsProgress = true;
MyBackgroundWorker.DoWork +=new DoWorkEventHandler(MyBackgroundWorker_DoWork);
MyBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(MyBackgroundWorker_ProgressChanged);
MyBackgroundWorker.RunWorkerCompleted +=new RunWorkerCompletedEventHandler(MyBackgroundWorker_RunWorkerCompleted);
MyBackgroundWorker.RunWorkerAsync();

现在,为了向主窗体(TopViewForm 的实例)报告进度,Enumerator 中的线程正在使用一些适当的用户对象调用 ReportProgress。我假设 ReportProgress 将以 ProgressChanged 事件的形式到达并在主 UI 线程上执行,主 UI 线程是创建 Enumerator 本身的线程(即不是 BackgroundWorker 的线程)。

鉴于这种情况,当我尝试在主进程线程上的 TreeView 中设置一个节点以响应来自该对象的事件时,我怎么可能遇到跨线程冲突错误? ProgressChanged 绝对似乎在主进程线程上运行,查看调用堆栈。

那么我假设 Application.Run 会生成一个新线程并使用它运行表单?但文件另有说明。要么我犯了一个愚蠢的错误,要么这里有一些我不明白的地方。

有人有什么想法吗?

【问题讨论】:

  • Bgw 与 Application.Run() 密切合作,因此将其移动到表单内。
  • 你们俩的想法都很好。如果我在表单内移动它,它可以正常工作。
  • 好吧,第一个添加它作为答案的人得到了积分:)

标签: c# winforms multithreading


【解决方案1】:

我相信 progress changed 事件在Application.Run 被首次调用之前运行。如果您不从Main 启动后台工作程序,而是从其中一种表单中启动,您将确定在创建后台工作程序并开始报告进度时消息循环已经存在。

【讨论】:

    【解决方案2】:

    BackgroundWorker 依赖于当前设置的 SynchronizationContext 才能运行。 ProgressChanged 事件以SendOrPostCallback Delegate 的形式实现,正如 msdn 文档中所述,SendOrPostCallback 表示您希望在将消息分派到同步上下文时执行的回调方法。在表单设计器中将 BackgroundWorker 添加到表单会正确设置 SynchronizationContext。在您的情况下,BackgroundWorker 没有分配 SynchronizationContext。

    【讨论】:

    • 啊,这才是真正的正确答案。感谢您提供的信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多