自学内容网 自学内容网

Winform Invoke与BeginInvoke

BeginInvoke与Invoke

BeginInvoke与Invoke联系

Invoke和BeginInvoke方法由ISynchronizeInvoke接口提供,且都需要一个委托对象作为参数。主要用于子线程操作主线程UI的控件,修改控件属性等。

BeginInvoke与Invoke区别

  • Invoke同步运行,会等待代码运行完之后返回,线程会阻塞。
  • BeginInvoke异步运行,调用之后立即返回,不会等待修改控件代码执行完,不会阻塞。

BeginInvoke与Invoke使用场景

  • 若后台线程在更新UI界面且不需要等待,则应该使用BeginInvoke方法进行异步操作。
  • 若后台线程在更新UI界面并且需要等待,则应该使用Invoke方法进行同步操作。

BeginInvoke与Invoke软件中执行顺序

private Thread invokeThread;
private delegate void invokeDelegate();
private void StartMethod(){
   //C代码段......
   Control.Invoke(new invokeDelegate(invokeMethod));
  //D代码段......
}

private void invokeMethod(){
  //E代码段
}

private void butInvoke_Click(object sender, EventArgs e) {
   //A代码段.......
   invokeThread = new Thread(new ThreadStart(StartMethod));
   invokeThread.Start();
   //B代码段......
}

A——>(Start一开始B和StartMethod的C就同时执行)—->(C执行完了,不管B有没有执行 完,invokeThread把消息封送(invoke)给UI线程,然后自己等待)—->UI线程处理完butInvoke_Click消息后, 处理invokeThread封送过来的消息,执行invokeMethod方法,即代码段E,处理往后UI线程切换到invokeThread线程。

Task与Invoke和BeginInvoke之间的组合使用

       //主线程点击按键
       private  void button1_Click(object sender, EventArgs e)
       {
           //子线程
           Task.Run(() =>
           {
               for (int i = 0; i < 10; i++)
               {
                   t1++;
                   this.lblTask1.BeginInvoke(new MethodInvoker(() =>
                   {
                       lblTask1.Text = t1.ToString();
                       //在这里延时会阻塞主线程,导致界面卡顿,需要放在BeginInvoke外面
                       //Thread.Sleep(500);
                   }));
                   //在子线程延时等待,不阻塞主线程
                   Thread.Sleep(500);
               }
           });
       }

由于Invoke和BeginInvoke都是操作的主线程,所以尽量避免在子线程调用Invoke和BeginInvoke方法里再放其他延时操作,这样会导致界面卡顿的现象。

C#窗体子线程调用主线程控件方法

Winform中子线程调用主线程控件方法
 this.Invoke(new Action(() =>
 {
     //调用主线程控件
 }));
 this.BeginInvoke(new Action(() =>
 {
     //调用主线程控件
 }));
WPF中子线程调用主线程控件方法
Application.Current.Dispatcher.Invoke(((Action)delegate ()
{
    // 在主线程中执行需要操作的UI代码
}));
await Application.Current.Dispatcher.BeginInvoke(((Action)delegate ()
{
    // 在主线程中执行需要操作的UI代码
}));

参考:

C# Invoke和BeginInvoke-CSDN博客

C#及WPF多线程定义和使用2(Task)_wpf task-CSDN博客


原文地址:https://blog.csdn.net/lvxingzhe3/article/details/143830344

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!