同时执行两个单独的方法

时间:2014-08-18 11:50:40

标签: c# .net wpf multithreading backgroundworker

我尝试使用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
}

6 个答案:

答案 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都使用的共享资源,则必须与任何同步原语(例如MutexSemaphoreManualResetEvent进行同步。等)适合您的场景。

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

注意,我建议你研究一下更现代的库,以便进行并行工作,例如.NET 4.0中引入的Task Parallel Library。具体来说,请查看TaskParallel类。

修改

根据评论中的问题,让我们看看使用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);

您还可以获得cancellationcontinuation以及async-awaitTask单元一起使用的好处,这样可以更轻松地进行并行编程。< / 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; 。要小心螺纹应用程序很难调试,如果处理不当可能会导致奇怪的结果。