13五/101
Winform跨线程操作控件的办法.
Hello,我是Snake,欢迎阅读我的文章--Winform跨线程操作控件的办法.
今天写了个程序,碰到了这个问题:
线程间操作无效: 从不是创建控件 [控件名称] 的线程访问它。
我现在正在使用vs2010英文版,平常也很少看那些有的没的文字,而且在写程序的时候很"明智"的异常捕获并且写进日志里去,所以没有出现那个可爱的调试状态下出现异常的那个小框框.
我在上网查了一会儿,有人说直接设置控件的CheckForIllegalCrossThreadCalls属性为false,但是因为可能的不安全因素所以还是不用的好.当然还有写一个委托来同步调用.但是我觉得它有点麻烦,就放弃用委托同步了.
后来我搞了好多种写法,都摆脱不了这个怨念,最终也摆脱了异常捕获并抛出了这个小框框.
框框上明确的说道:"线程间操作无效: 从不是创建控件 [控件名称] 的线程访问它。"但是在框框的Suggestion列表中显示出了一条项目,大意是:"如何:对 Windows 窗体控件进行线程安全调用.",我点开它,并且跳进了MSDN.
原来在MSDN上就有教咱如果夸线程操作控件啊.亏我还Google半天呢.
MSDN上的办法就是使用委托来同步调用控件的.具体方法我也就不卖关子了.因为MSDN上的代码比较繁多,所以我稍微改进了一下.
//首先声明一个委托.
delegate void SetValueDelegate(int val);
//模仿程序中的跨线程调用
public void Progress()
{
Thread t = new Thread(() =>
{
//跨线程由此开始
SetValue(100);
});
t.Start();
}
//关键部分在这里
public void SetValue(int val)
{
//InvokeRequired属性当非创建本控件线程操作的时候
//它返回true,此时使用窗体(该控件的创建者)的Invoke方法创建同步调用.
//妙哉,妙哉!
if (ProgressBar1.InvokeRequired)
{
var svd = new SetProgressValue(SetValue);
this.Invoke(svd, val);
}
else
{
ProgressBar1.Value = val;
}
}
好了,就是这样,非讨论文章就越精炼越好.希望能帮到你.
最后附上MSDN的地址:这里

2010年05月14日 09:10
嘿嘿。占个沙发,踩踩。