Ron*_*fca 5 c# thread-safety visual-studio-2008
我最近更新了一个从VS2003到VS2008的应用程序,我知道我将处理一系列"跨线程操作无效:控制'myControl'从一个线程访问,而不是它创建的线程"我在处理这个我所信奉的是正确的方法(参见下面的代码示例).我遇到了许多需要类似修复的控件.不希望为非UI线程访问的每个标签,文本框等都有类似的代码.仅为整个应用设置CheckForIllegalCrossThreadCalls = false会产生什么影响?
我找到了一个CodeProject文章,其中包含各种变通方法,并在底部发出警告,未设置该属性.我正在寻找关于这个问题的其他意见/经验.
private void ShowStatus(string szStatus)
{
try
{
if (this.statusBar1.InvokeRequired) { BeginInvoke(new MethodInvoker(delegate() { ShowStatus(szStatus); })); }
else { statusBar1.Panels[0].Text = szStatus; }
}
catch (Exception ex)
{
LogStatus.WriteErrorLog(ex, "Error", "frmMNI.ShowStatus()");
}
}
Run Code Online (Sandbox Code Playgroud)
我发现另一篇文章提出了一些可能的解决方案SO Question 2367718
当你没有调试时,你仍然会遇到问题.
从Control.CheckForIllegalCrossThreadCalls的文档:
请注意,在调试器外部启动应用程序时,非法的跨线程调用将始终引发异常.
你需要纠正这些问题.
话虽如此,你提到:
不希望为非UI线程访问的每个标签,文本框等都有类似的代码.
我会重新考虑这个立场.您应该尝试将在单独线程上运行的逻辑移动到单独的方法或类中,这反过来会使调用回调到UI更加简单.随着时间的推移,这将使您的代码更加可靠和可维护.
请注意,您也可以使用Control.Invoke在一次调用中编组对UI的一整套调用,而不是单独执行每个单个集操作.当你完成时,确实不应该有那么多.
编辑:
例如,听起来你正在加载数据.假设你有(在你的后台线程上)你的数据加载方法:
var myData = LoadData();
this.Invoke( new Action( () =>
{
// Just set all of your data in one shot here...
this.textBox1.Text = myData.FirstName;
this.textBox2.Text = myData.LastName;
this.textBox3.Text = myData.NumberOfSales.ToString();
}));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6152 次 |
| 最近记录: |