在.net中实现多线程的不同方法有哪些

时间:2010-04-07 19:22:02

标签: .net multithreading backgroundworker begininvoke conceptual

我已经与多线程战斗了几天。

我不明白multithreading的不同方式。我已经阅读了一些关于backgroundWorker的内容,关于创建线程对象的一点点。 昨天我在delegate示例中看到通过调用BeginInvoke来实现多线程。

我不明白multithreading的这些不同方式或同一工作在同一背景课上。 请帮我说清楚。

3 个答案:

答案 0 :(得分:2)

我非常喜欢这个explanations。也许他们也会帮助你 然后,Jon Skeet也有this article

答案 1 :(得分:1)

没有GUI的任何线程都是后台工作者。 在dot net上使用线程的常用方法是创建一个线程对象并给它一个线程main方法,这样,这个函数将在后台执行 我认为您应该阅读以下书籍以获得关于该主题的更深入的知识

  • .NET多线程
  • C#Threading Handbook

另外在GUI应用程序上,比如WPF或win form app,唯一可以更改gui元素的线程是主线程(gui线程),所以你应该使用begininvoke使用这个线程并放回一个回调来改变gui,否则你会得到一个无效的操作异常。

使用线程的另一种方法是使用.net这样的线程池

   ThreadPool.QueueUserWorkItem(new WaitCallback(delegateMethod), data);

 private void delegateMethod(object data){
   //some stuff
 }

答案 2 :(得分:0)

首先,我要说除非绝对必要,否则不要进行多线程处理。试图以最熟练的方式避免和优化您的代码将以某种方式做得最好,因为您将避免多重麻烦。

其次,BackgroundWorker课程是一个好的开始。您需要实例化您需要运行线程的实例数。对于每个人,您必须编写其DoWork()方法的代码。通过调用BackgroundWorker.RunWorkerAsync()方法启动其操作时,将调用此方法。您想要放在DoWork()事件中的代码是在应用程序的主线程忙于处理其他内容时应在后台异步运行的代码。另外两个事件:ProgressChanged()RunWorkerCompleted()用于ReportProgress()或定义当线程完成其工作时要做什么,无论结果如何(异常,正确结束等)。我大部分时间都使用BackgroundWorker,从我的拙见来看,它最简单易用。

第三,你可以使用System.Threading.Thread类。它比定义一个DoWork()事件并通过调用另一个方法使它发生更复杂一些。你必须熟悉delegates。简而言之,委托是用于在后台执行某些工作的方法或函数的类型。对于这些委托,您可能有多个相同委托类型的方法,正如我刚才所说,委托是方法类型。您可能有多个delegate的引用。您可能会将其视为方法签名。然后,当有时间使用它时,您必须引用所需委托的方法。使用System.Threading.Thread类,您需要注意ThreadStart delegate

delegate void DoWork(object sender);

private void btnProcessWork_Click(object sender, EventArgs e) {
    DoWork doWork = SimpleDoWorkMethod;
    // Then start using the delegate.
    Thread t = new Thread(new ThreadStart(doWork));
    t.Start(); // Launch the thread in background...
    // Do something else while the thread is working !!!
}

private void SimpleDoWorkMethod(object s) {
    // Do some work here...
}

第四,将代表视为事件,因为事件基于代理。事实上,您提供了一个方法,用于处理类似Button_Click()的事件。要以编程方式将btnProcess.Click事件与btnProcess_Click()方法关联,您需要编写:

btnProcess.Click += new EventHandler(btnProcess_Click);

这里你要做的是使btnProcess.Click事件引用你的btnProcess_Click()方法。注意带有ThreadStart委托的EventHandler委托。它们用于完全相同的目的,但是用于两种不同的现实(GUI事件响应和多线程)。

第五,不要忘记在访问变量之前锁定变量,而另一个变量可能几乎同时访问它,然后抛出一个交叉线程或者异常,这个,即使是原始类型,但更具体地说是集合,因为它们不是线程安全的。

希望这有点帮助! =)