我尝试使用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
}
答案 0 :(得分:7)
如前所述,同时执行IO不会为您带来多少利润。
如果计算重,是的,您可以使用BackgroundWorker
,甚至更好Task
(来自Task Parallel Library)。
Task t1 = Task.Run( () => HeavyMethod1() );
Task t2 = Task.Run( () => HeavyMethod2() );
await Task.WaitAll(new Task[] {t1, t2});
答案 1 :(得分:2)
这很大程度上取决于你想要实现的目标,但是,它可以彼此独立地执行它们,但这并不意味着你将在同一时间执行它们。 (例如,如果您有单核cpu,则不可能同时安排在CPU上执行2个线程:))。
创建线程是一个巨大的性能损失(你可以很容易地看到自己,尝试在循环中创建线程,你会看到:))。更好的想法是创建一个ThreadPool任务,让.NET决定是否需要多个线程来执行您的操作(您可以从http://msdn.microsoft.com/en-us/library/0ka9477y(v=vs.110).aspx开始)。
编辑:
检查@PatrickHofman答案,查看创建任务的代码。
答案 2 :(得分:1)
是的,有可能。今天许多应用程序使用多个线程来并行工作。 在做这样的工作时,人们也必须注意到陷阱。
例如,如果您有WorkerA和WorkerB都使用的共享资源,则必须与任何同步原语(例如Mutex
,Semaphore
,ManualResetEvent
进行同步。等)适合您的场景。
另外,请注意,启动新线程并不是免费的,每个线程都有开销,例如每个线程都有1MB堆栈。
注意,我建议你研究一下更现代的库,以便进行并行工作,例如.NET 4.0中引入的Task Parallel Library
。具体来说,请查看Task
和Parallel
类。
修改强>
根据评论中的问题,让我们看看使用Task
vs 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);
您还可以获得cancellation,continuation以及async-await与Task
单元一起使用的好处,这样可以更轻松地进行并行编程。< / p>
答案 3 :(得分:1)
您是否看到Microsoft在.NET 4.5中添加到.NET Framework中的新异步方法?虽然它们实际上不会在同一时间读取两个文本文件,但它们肯定会提高应用程序的性能。例如,您可以使用TextReader.ReadToEndAsync
Method(取自StreamReader.ReadToEndAsync
Method页面):
String result;
using (StreamReader reader = File.OpenText("existingfile.txt"))
{
Console.WriteLine("Opened file.");
result = await reader.ReadToEndAsync();
Console.WriteLine("Contains: " + result);
}
有关这些新异步方法的详细信息,请参阅MSDN上的Asynchronous File I/O页面。
答案 4 :(得分:1)
您可以使用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);
答案 5 :(得分:0)
很多概念都可以让你这样做,因为你已经强调一次执行两种方法,你可以选择多线程。 任务并行也有助于实现您的目标。 如果您想要更具体的答案,只需使用Google &#34; .NET中的多线程&#34; 。要小心螺纹应用程序很难调试,如果处理不当可能会导致奇怪的结果。