【发布时间】:2015-11-06 15:04:21
【问题描述】:
我有一个与DataGridView refresh causes "Not Responding" application (but only when not in Visual Studio) 非常相似的问题
在将数据加载到我的 Winforms 应用程序表单时,我暂时禁用了填充表单并包含所有控件的面板,并在完成后将其重新启用。
与示例一样,我使用 BackgroundWorker 加载数据并使用线程安全的 bgWorkerSend_ProgressChanged 或 bgWorkerSend_RunWorkerCompleted 与 UI 交互。
我还有一个 Windows 窗体计时器,它会在 5 分钟空闲时间后以与窗体相同的方式刷新。
奇怪的是,在初始化加载结束时,面板被正确启用,而在后面的刷新中,应用程序进入“无响应”模式,并永远保持在那里。此外,这只发生在我直接执行应用程序时。如果从 Visual Studio 执行,它在初始加载和刷新时都能正常工作。
private void _bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (e.ProgressPercentage == 100)
{
// re-enable panel
panel1.Enabled = true;
// the below is never reached !!?
AnyInstruction();
}
}
【问题讨论】:
-
这可能是一个跨线程问题,请尝试在 UI 线程上启用面板。
-
我的理解是_bw_ProgressChanged的内容是在UI线程上执行的,对不对?
-
只有在正确使用 BGW 时才会出现这种情况。强烈暗示你没有。就像从工作线程而不是 UI 线程调用 RunWorkerAsync() 方法一样。使用 Debug > Windows > Threads 调试器窗口进行验证。
-
我仔细检查并使用了 VS Debug > Windows > Thread 和 RunWorkerAsync 上的断点,当它停在那里时,它显示它来自主线程,无论是在初始化加载时,还是在刷新时计时器。我假设 Windows 窗体 timer_Tick() 是从主线程执行的。
-
如果有帮助,实际上
_bw.RunWorkerAsync()是从presenter 类中的事件处理程序启动的,而不是直接从表单类启动的。该事件在演示者和表单(视图)之间关联:_view.DataLoaded += DataLoaded;
标签: c# winforms .net-3.5 backgroundworker