c#有关多线程导致的常见问题--从不是创建控件的线程访问、不能调用invoke

1.System.InvalidOperationException:“线程间操作无效: 从不是创建控件“”的线程访问它。”

这个问题是我们在子线程中更新UI时常常发生的问题。
解决方法1:
在更新UI前用this.Invoke()将里面的内容放在当前控件所在的线程上执行。除了用this.Invoke() ,也可以用RichTextBox.Invoke()等等其他控件。
如下所示:

this.Invoke(new EventHandler(delegate
{
    RichTextBox.Select(RichTextBox.TextLength, 0);
        //滚动到控件光标处   
        RichTextBox.ScrollToCaret();
    RichTextBox.AppendText(info + Environment.NewLine);
}));

解决方法2:
通过UI线程的SynchronizationContext的Post/Send方法更新。
定义一个变量(可定义为一个静态的变量,所有地方都可使用):

 public static SynchronizationContext m_SyncContext = null;

尽量在窗体构造函数或FormLoad事件中给变量赋值为当前线程。

 m_SyncContext = SynchronizationContext.Current;

需要转线程的地方:

public static void Write(string info)
{
    m_SyncContext.Post(AddRichText, info);//将要转线程的代码放在AddRichText中
}
private static void AddRichText(object info)//传入参数必须为object 
{
    RichTextBox.Select(RichTextBox.TextLength, 0);
    //滚动到控件光标处   
    RichTextBox.ScrollToCaret();
    RichTextBox.AppendText(info + Environment.NewLine);
}

2.System.InvalidOperationException:“在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。”

第一个问题解决后常常会导致这个问题,这是由于电脑执行的太快,控件的初始化未完成造成。
可以等待控件初始化完成后再执行(不建议这样的方式),

while (!this.IsHandleCreated) 
{ 
    ; 
} 
this.Invoke(...);

或者直接跳过,但是这个就是不会执行了,如果逻辑是不能跳过的,建议出现问题1的时候选择解决方法2。

if( this.IsHandleCreated )
{
   this.Invoke(...);
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yyuanyuxin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值