几天来我一直在与多线程作斗争。
我不明白有什么不同的方式multithreading
。我已经阅读了一些backgroundWorker
关于创建线程对象的内容。昨天我在示例中看到delegate
通过调用BeginInvoke
.
我不明白这些不同的方式是multithreading
在同一个背景类上工作还是相同的工作。请帮我说清楚。
几天来我一直在与多线程作斗争。
我不明白有什么不同的方式multithreading
。我已经阅读了一些backgroundWorker
关于创建线程对象的内容。昨天我在示例中看到delegate
通过调用BeginInvoke
.
我不明白这些不同的方式是multithreading
在同一个背景类上工作还是相同的工作。请帮我说清楚。
任何没有 GUI 的线程都是后台工作者。在 dot net 上,使用线程的常用方法是创建一个线程对象并为其提供一个线程 main 方法,因此,该函数将在后台执行,我认为您应该阅读以下书籍以更深入地了解该主题
此外,在一个 GUI 应用程序上,如 WPF 或 win form 应用程序,唯一可以改变 gui 元素的线程是主线程(gui 线程),所以你应该使用 begininvoke 使用这个线程并放一个回调来改变 gui,否则你会得到一个无效的操作异常。
使用线程的另一种方法是使用 .net 的线程池,如下所示
ThreadPool.QueueUserWorkItem(new WaitCallback(delegateMethod), data);
private void delegateMethod(object data){
//some stuff
}
首先,我要说的是,除非绝对必要,否则不要使用多线程。尝试以最熟练的方式避免和优化您的代码会做得最好,因为您将避免多线程问题。
其次,BackgroundWorker类是一个好的开始。您将需要实例化尽可能多的实例,因为您需要运行线程。对于它们中的每一个,您都必须编写其DoWork()方法。当您通过调用BackgroundWorker.RunWorkerAsync()方法启动其操作时,将调用此方法。您要放置在 DoWork() 事件中的代码是在应用程序的主线程忙于其他事情时应在后台异步运行的代码。另外两个事件:ProgressChanged()和RunWorkerCompleted()用于ReportProgress()或者定义线程完成工作后要做什么,无论它是什么结束(异常,正确结束等)我大部分时间都使用BackgroundWorker,因为它是,在我谦虚的角度来看,最简单的用过的。
第三,您可以使用System.Threading.Thread类。它比仅仅定义一个 DoWork() 事件并通过调用另一个方法使其发生要复杂一些。您必须熟悉代表。简而言之,委托是用于在后台执行某些工作的方法或函数的类型。至于这些委托,你可能有多个相同委托类型的方法,就像我刚才说的,委托是方法类型。您可能有一个委托的多个引用。您也可以将其视为方法签名。然后,当需要使用它时,您必须为想要的委托引用一个方法。使用 System.Threading.Thread 类,您需要留意ThreadStart 委托。
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 事件响应和多线程)。
第五,不要忘记在访问变量之前锁定一个变量,而另一个人可能想同时访问它,然后抛出一个跨线程左右的异常,这甚至对于原始类型,但更具体地说是对于集合,如它们不是线程安全的。
希望这个对你有帮助!=)