Har*_*dik 2 c# multithreading winforms
我使用VS 2010,C#构建应用程序.
我BackgroundWorker在我的申请中使用.
当我点击按钮代码从数据库获取记录并显示到Datagrid.但问题是,当我从代码运行它时工作正常,但当我运行程序.exe所以它正在挂起.
//Declared delegate
delegate void SetControlPropertyThreadSafeDelegate(Control control, string propertyName, object propertyValue);
//Declared method to run control Thread safe
public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
{
if (control.InvokeRequired)
{
control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
}
else
{
control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
}
}
//calling method like below
SetControlPropertyThreadSafe(dataGridView1, "DataSource", dtGrid2);
Run Code Online (Sandbox Code Playgroud)
我不明白我做错了.为什么该计划挂起?
void SetControlPropertyThreadSafe(...)
Run Code Online (Sandbox Code Playgroud)
像这样的方法存在很大的问题.遗憾的是很难根除,也有方法上,这样推荐这太多的职位.问题是它让一个程序员沉睡,它是"安全的"所以肯定不是问题的原因.将问题转化为不可解决的问题.
关于它绝对没有"安全":
使用Control.Invoke()是危险的,它很容易导致死锁.当UI线程中的代码执行某些不明智的操作(如等待工作线程完成)时触发.只有当你背对墙时才使用Invoke(),实际上需要返回值.当你发现那是必要的,那么不要这样做,它总是比赛,除非你禁用UI.始终使用BeginInvoke().
它隐藏了一个消防水带问题.你会痴迷于调用方法来更新每一个控件,而不是考虑这个导致的问题.这是用调用请求打击UI线程.这样做的速度比人眼可以看到的高50倍,你会埋葬UI线程.它永远无法赶上调用请求,只要它调度一个然后另一个等待执行.UI线程现在停止处理其正常职责,例如绘制窗口和处理用户输入.它看起来很冷,就像你直接运行这段代码一样
当用户关闭窗口但您的工作线程保持驾驶时,会发生非常不愉快的事情.调用不再存在的窗口.这通常会发出响亮的声音,因此诊断起来并不太难.有时它不会,不可能调试,在停止线程和允许窗口关闭之间存在不可避免的线程竞争,只能通过不关闭窗口而是隐藏它来解决.
你的问题是第二个子弹.它挂起是因为你的代码现在运行得更快.Invoke()调用隐藏了调试器中的问题.完全摆脱这个代码,它是危险的,并从例如List <>的dbase查询中收集结果.偶尔将它传递给ReportProgress()方法,这样就不会阻塞UI线程.在调用后重新创建List,因此它是线程安全的.
| 归档时间: |
|
| 查看次数: |
1290 次 |
| 最近记录: |