同时执行两个独立的方法

本文关键字:两个 独立 方法 执行 | 更新日期: 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都使用共享资源,则必须使用适合您的场景的任何同步原语(例如MutexSemaphoreManualResetEvent等)进行同步。

另外,请注意,旋转新线程并不是免费的,每个线程都有开销,例如每个创建一个1MB的堆栈。

注意,我建议你看看更现代的库来做并行工作,比如。net 4.0中引入的Task Parallel Library。具体来说,查看TaskParallel类。

编辑

根据你在评论中的问题,让我们看看使用TaskBackgroundWorker是什么样子的:

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中的多线程"。注意线程应用很难调试,如果处理不当可能会导致奇怪的结果。