C# BeginInvoke 和 Thread.Start 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1226457/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 13:55:04  来源:igfitidea点击:

Difference between BeginInvoke and Thread.Start

c#.netmultithreadingdelegates

提问by Ashish Ashu

I have a dialog based application in which I will delegating the I/O operation read write to different thread.

我有一个基于对话框的应用程序,我将在其中将 I/O 操作读写委托给不同的线程。

I just want to clear is there any difference between two approaches..

我只想弄清楚两种方法之间有什么区别..

First approach: ( I am doing this in ,my main form -Form.cs)

第一种方法:(我在我的主要表单 -Form.cs 中执行此操作)

delegate void Action();
Action _action = new Action(Method);
this.BeginInvoke(_action);

Second approach:

第二种方法:

Thread th = new  Thread( new ThreadStart(_action));
th.Start();

I noticed that BeginInvoke hangs the UI for a second while second approach don't ..

我注意到 BeginInvoke 将 UI 挂起一秒钟,而第二种方法则不会 ..

Please help

请帮忙

采纳答案by Kenan E. K.

BeginInvokewill post the action in the message queue of the message pump on the same thread as the Form, it will not create a new thread.

BeginInvoke将在消息泵的消息队列中发布与 相同的线程中的操作Form,它不会创建新线程。

Control.BeginInvokebehaves similar to an asynchronous thread start, but has important internal differences.

Control.BeginInvoke行为类似于异步线程启动,但具有重要的内部差异。

Read in further detail an article here.

此处详细阅读一篇文章。

回答by Sk93

the difference would be that the BeginInvoke method simply calls the delegate asynchronously on the SAME thread.

不同之处在于 BeginInvoke 方法只是在 SAME 线程上异步调用委托。

Using the Thread.Start, you'll be creating an entirely different thread.

使用 Thread.Start,您将创建一个完全不同的线程。

Thread.Start will definately give you better performance!

Thread.Start 肯定会给你更好的性能!

回答by Thomas Levesque

BeginInvokes executes the delegate asynchronously on the UI thread (which is why it hangs the UI), by posting a message to the window. That's what you need to do if the code in the delegate accesses the UI.

BeginInvokes 通过向窗口发送消息,在 UI 线程上异步执行委托(这就是它挂起 UI 的原因)。如果委托中的代码访问 UI,这就是您需要执行的操作。

The approach with Thread.Start executes the delegates on a new, independant thread.

使用 Thread.Start 的方法在新的独立线程上执行委托。

回答by Timbo

Thread.Startruns it on your new Thread.

Thread.Start在您的新Thread.

Control.BeginInvokeruns the method on the thread that the Control this belongs to. If you are currently on the thread of the control, the method is not run until you return control to the message loop, e.g. exit your event handler.

Control.BeginInvoke在该控件所属的线程上运行该方法。如果您当前在控件的线程上,则该方法不会运行,直到您将控制权返回到消息循环,例如退出您的事件处理程序。

回答by lb.

Try this.

尝试这个。

class Form1: Form
{
   public void ButtonWasClicked(object sender, EventArgs e)
   {
       /* Call the UI's Invoke() method */
       this.Invoke((MethodInvoker)delegate()
       {
           /* Stuff to do.. you can access UI elements too without
            * the nasty "Control accessed from another thread.."
            * Use BeginInvoke() only if you have code after this section
            * that you want the UI to execute without waiting for this 
            * inner blockto finish. 
            */
       });
   }
}

Regarding BeginInvoke(), it is used so the function will return immediately and the next line will be executed and so on and so forth without waiting for the method to finish.

关于BeginInvoke(),使用它是为了让函数立即返回并执行下一行等等,而无需等待方法完成。

The difference is that if you create a thread you will have more control over it just like any other thread. You will run into CrossThreadExceptions! Whereas if you use IAsyncResult and BeginInvoke(), you will not have control over the execution flow of the asynchronous operation as it's managed by the runtime.

不同之处在于,如果您创建一个线程,您将像任何其他线程一样对其拥有更多控制权。你会遇到CrossThreadExceptions!而如果您使用 IAsyncResult 和 BeginInvoke(),您将无法控制异步操作​​的执行流程,因为它由运行时管理。

With invocation you can also send more parameters to a method and have a method being called once the operation is finished.

通过调用,您还可以向方法发送更多参数,并在操作完成后调用方法。

MyDelegateWithTwoParam del = new MyDelegateWithTwoParam(_method);
AsyncCallback callback = new AsyncCallback(_callbackMethod);
IAsyncResult res = del.BeginInvoke(param1, param2, callback, null);

private void _callbackMethod(IAsyncResult iar) {
   /* In this method you can collect data that your operation might have returned.
    * If MyDelegateWithTwoParam has a return type, you can find out here what i was. */
}

I've widely used both for UI development. I would use threads more for service-like objects. (Think of an object that stays and listens for TCP connections) and asynchronous methods for background work behind a UI (have a look at BackgroundWorker too). Don't worry if the first approach took an extra second to start: Thread.Abort() is not always your best solution either. Try _abort flags in your process code and lock it.

我已经广泛用于 UI 开发。我会更多地将线程用于类似服务的对象。(想想一个保持并侦听 TCP 连接的对象)和 UI 后面后台工作的异步方法(也可以看看 BackgroundWorker)。如果第一种方法需要额外的一秒钟才能启动,请不要担心:Thread.Abort() 也不总是您的最佳解决方案。在您的流程代码中尝试 _abort 标志并锁定它。

Hope I've answered the question.

希望我已经回答了这个问题。

Leo Bruzzaniti

里奥·布鲁扎尼蒂

回答by Don Kirkby

As others have posted, Thread.Start will launch a new thread, and Control.BeginInvoke() will run code on the UI thread (necessary if you want to change a field's value, for example).

正如其他人发布的那样,Thread.Start 将启动一个新线程,而 Control.BeginInvoke() 将在 UI 线程上运行代码(例如,如果您想更改字段的值,则这是必需的)。

However, I have found that the simplest technique for executing a background task in WinForms is to use a BackgroundWorker. You drop it onto a form, wire up the events, and call RunWorkerAsync(). Then you write your background task in the DoWork event. Any UI refresh can be put in the RunWorkerCompleted event.

但是,我发现在 WinForms 中执行后台任务的最简单技术是使用BackgroundWorker。你把它放到一个表单上,连接事件,然后调用 RunWorkerAsync()。然后在 DoWork 事件中编写后台任务。任何 UI 刷新都可以放在 RunWorkerCompleted 事件中。

Using a BackgroundWorker avoids all the annoying thread handling and IsInvokeRequired stuff.

使用 BackgroundWorker 避免了所有烦人的线程处理和 IsInvokeRequired 的东西。

Here's a more detailed how-to article.

这是一篇更详细的操作方法文章