winform中 跨线程启动UI

摘要:
C#的winform程序中,是不可以从UI窗口主线程之外的线程去直接操作窗口控件的。确切的解释是,不能从创建控件的线程以外的线程去处理控件的操作,比如修改属性等。方法二,通过Control.Invoke调用委托的方式来执行。

C#的winform程序中,是不可以从UI窗口主线程之外的线程去直接操作窗口控件的。
确切的解释是,不能从创建控件的线程以外的线程去处理控件的操作,比如修改属性等。
以下是跨线程操作控件的报错信息:线程间操作无效: 从不是创建控件“textBox4”的线程访问它
解决办法
解决方案有两个:
方法一,设定Control类的CheckForIllegalCrossThreadCalls属性为false,不检测跨线程访问。也可以对Form直接设定这个属性,Form也是Control子类,该窗口下的所有控件都不检测。
方法二,通过Control.Invoke调用委托的方式来执行。
如果有多个线程要同时操作控件的话,推荐使用方法二,比较安全一些,方法一在某些情况下会报错,比如UI线程对这个控件在控件表面绘图,还没释放时,子线程也对这个控件进行绘图,就会报错了。

委托解决的使用方式
textBox4.Invoke(.....) 或 textBox4.BeginInvoke(....)
示例
public delegate void InvokeDelegate();

private void Invoke_Click(object sender, EventArgs e)
{
myTextBox.BeginInvoke(new InvokeDelegate(InvokeMethod));
}

public void InvokeMethod()
{
myTextBox.Text = "Executed the given delegate ";
}
-----------------------------------------------------------------
因为你这个控件是主线程创建的,它依附于创建窗体的主线程.因此,要在子线程去访问占资源的类型,我们需要跨线程调用.textBox4.InvokeRequire用于判断是否需要跨线程,返回True为需要跨线程,此时你需要定义一个委托类来将一个含赋值语句的方法封装起来,通过textBox4.Invoke来调用这个委托.代码如下:
public delegate void SetTextHandler(string text);
private void SetText(string text)
{
if(textBox4.InvokeRequired==true)
{
SetTextHandler set=new SetTextHandler(SetText);//委托的方法参数应和SetText一致
textBox4.Invoke(set,new object[]{text}); //此方法第二参数用于传入方法,代替形参text
}
else
{
textBox4.Text=text;
}
}
那么fun2函数可以改写成:
void fun2()
{
str1 = long.Parse(textBox1.Text);
str2 = long.Parse(textBox2.Text);

lock (this)

for (long i = str2; i <= str1; i--)
{
sum1 = sum1 + i;

}
SetText( sum1.ToString());

}
注意那两句 str1 = long.Parse(textBox1.Text);也需要写成委托形式,读取数据的方法和赋值的方法类型.

免责声明:文章转载自《winform中 跨线程启动UI》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇微信支付服务商模式支付与普通微信支付的配置区别C#控件重绘学习(一)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

JMeter常用控件二、线程组

标签(空格分隔): Jmeter ##线程组 一. 线程组 一个虚拟的用户组,用于模拟一个或多个用户的操作。 线程组定义将对您的服务器执行特定测试用例的用户池。 **名称:**线程组的名称,可以为空,填写时需要需要具备实际意义。 **注释:**线程的注释,可以为空,填写时需要具备实际意义。 在取样器错误后要执行的动作 继续:如果取样器里的执行出现错误失...

ManualResetEvent的理解

首先弄清楚, ManualResetEvent 是WaitEventHandler(等待事件句柄)的一个子类。ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。可以通过将布尔值传递给构造函数来控制 ManualResetEvent 的初始状态,如果初始状态处于终止状态,为 true;否则...

winform进程、线程

随笔- 86 文章- 0 评论- 0 winform进程、线程 进程: 一般来说,一个程序就是一个进程,不过也有一个程序需要多个进程支持的情况。 进程所使用的类:Process 所需命名空间:System.Diagnostics; 可以通过进行来开启计算机上现有的程序: 1、使用静态方法Start();但必须要知道进程名 2、也可以实例化对象,来调用S...

Java多线程中static变量的使用

线程,是我们项目中绕不过的重点领域。提到线程,就常会听到线程安全的术语。那什么是线程安全呢?通俗点说,就是线程访问时不产生资源冲突。其实,这是一个有点难以定义的概念,不是很容易让人一听就懂的概念。“一个类可以被多个线程安全调用就是线程安全的”《Java并发编程实践》。     来说说静态变量、实例变量、局部变量在多线程下的安全问题吧!     (一)静态变...

Python 并发编程(一)之线程

常用用法 t.is_alive() Python中线程会在一个单独的系统级别线程中执行(比如一个POSIX线程或者一个Windows线程)这些线程将由操作系统来全权管理。线程一旦启动,将独立执行直到目标函数返回。可以通过查询一个线程对象的状态,看它是否还在执行t.is_alive() t.join() 可以把一个线程加入到当前线程,并等待它终止Python...

App性能优化浅谈

前言 前段时间给公司的小伙伴们进行了关于app性能优化的技术分享。这里我稍微整理一下也给大家分享一下。关于性能优化这个话题非常大,涉及面能够非常广,也能够非常深入。本人能力有限,不会给大家讲特别难懂,特别底层的东西。都是我们开发能着手去做的点。大家都在讲性能优化,但对于项目经验不够丰富的朋友非常难有一个概念。做优化的时候也会比較茫然,这里我就给大家指明方...