同时执行两个独立的方法
本文关键字:两个 独立 方法 执行 | 更新日期: 2023-09-27 18:18:23
我正在尝试同时使用Backgroundworker
(或者如果不可能使用另一种方法)执行两个单独的方法来获得性能。这个想法是在方法中做大量的计算。
这有可能吗?
private readonly BackgroundWorker _worker = new BackgroundWorker();
private readonly BackgroundWorker _worker2 = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;
_worker.DoWork += worker_DoWork;
_worker.RunWorkerAsync();
_worker2.WorkerReportsProgress = true;
_worker2.WorkerSupportsCancellation = true;
_worker2.DoWork += worker_DoWork2;
_worker2.RunWorkerAsync();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
// Do something
}
private void worker_DoWork2(object sender, DoWorkEventArgs e)
{
// Do something simultaneously with worker_DorWork
}
如前所述,同时进行IO操作不会为您带来太多利润。
如果计算是繁重的,是的,你可以使用BackgroundWorker
,或者更好的Task
(来自任务并行库)。
Task t1 = Task.Run( () => HeavyMethod1() );
Task t2 = Task.Run( () => HeavyMethod2() );
await Task.WaitAll(new Task[] {t1, t2});
这在很大程度上取决于你想要实现什么,但是是的,可以独立地执行它们,但这并不一定意味着你将在同一时间执行它们。(例如,如果你有单核cpu,这是不可能的2个线程被安排在cpu上执行在同一时间:))。
创建线程是一个巨大的性能冲击(你可以很容易地看到自己,尝试在循环中创建线程,你会看到:))。一个更好的主意是创建一个ThreadPool Task,让。net决定是否需要多个线程来执行你的操作(你可以从这里http://msdn.microsoft.com/en-us/library/0ka9477y(v=vs.110).aspx开始)。
编辑:查看@PatrickHofman答案查看创建任务的代码
是有可能的。现在很多应用程序都使用多个线程来并行工作。在做这样的工作时,人们也必须注意到陷阱。
例如,如果WorkerA和WorkerB都使用共享资源,则必须使用适合您的场景的任何同步原语(例如Mutex
、Semaphore
、ManualResetEvent
等)进行同步。
另外,请注意,旋转新线程并不是免费的,每个线程都有开销,例如每个创建一个1MB的堆栈。
注意,我建议你看看更现代的库来做并行工作,比如。net 4.0中引入的Task Parallel Library
。具体来说,查看Task
和Parallel
类。
编辑
根据你在评论中的问题,让我们看看使用Task
和BackgroundWorker
是什么样子的:
BackgroundWorker:
_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;
_worker.DoWork += worker_DoWork;
_worker.RunWorkerAsync();
任务:
var task = Task.Run(worker_DoWork);
或者如果你在。net 4.0上:
var task = Task.Factory.StartNew(worker_DoWork);
您还可以获得取消、延续以及在Task
单元中使用async-await的好处,这使得并行编程更加容易。
你看到微软在。net 4.5中添加到。net框架中的新的异步方法了吗?虽然它们实际上不会同时读取两个文本文件,但它们肯定会提高应用程序的性能。例如,您可以使用TextReader.ReadToEndAsync
方法(取自StreamReader.ReadToEndAsync
方法页面):
String result;
using (StreamReader reader = File.OpenText("existingfile.txt"))
{
Console.WriteLine("Opened file.");
result = await reader.ReadToEndAsync();
Console.WriteLine("Contains: " + result);
}
有关这些新的异步方法的更多信息,请参阅MSDN上的异步文件I/O页面。
可以使用TPL执行并行计算。它让你更容易去做耗时的工作,然后等待它完成。参见附带的示例。您需要使用Task.WaitAll()来等待所有任务完成,或者,TPL将等待您使用. result属性的所有任务,如下面的情况所示。
var startTime = DateTime.Now;
Task<int> longCalculationResult = Task.Factory.StartNew<int>(PerformSomeLongCalculations);
Task<int> longerCalculationResult = Task.Factory.StartNew<int>(PerformSomeEvenLongerCalculations);
//Task.WaitAll(); // Wait for both calculations to finish
// or you can access results of both tasks, which will wait for them to finish in the background
Console.WriteLine("{0}, {1}", longCalculationResult.Result, longerCalculationResult.Result);
var timeTaken = (DateTime.Now - startTime).TotalSeconds;
Console.WriteLine("It took {0} seconds to calculate the results.", timeTaken);
很多概念都允许你这样做,既然你强调一次执行两个方法,你可以选择多线程。任务并行性也有助于实现您的目标。如果你想要更具体的答案,只需谷歌一下"。net中的多线程"。注意线程应用很难调试,如果处理不当可能会导致奇怪的结果。