wpf 同时执行两个独立的方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25362655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:22:16  来源:igfitidea点击:

Execute two separate methods simultaneously

c#.netwpfmultithreadingbackgroundworker

提问by Vahid

I'm trying two execute two separate methods at the same time using Backgroundworker(or if not possible using another method) to gain performance. The idea is to do heavy calculations in methods.

我正在尝试使用Backgroundworker(或者如果不可能使用另一种方法)同时执行两个单独的方法来获得性能。这个想法是在方法中进行大量计算。

Is it possible at all?

有可能吗?

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
}

采纳答案by Yuval Itzchakov

Yes, it is possible. A lot of applications today consume multiple threads to do work in parallel. When doing such work, one has to notice the pitfalls too.

对的,这是可能的。今天的许多应用程序都使用多个线程来并行工作。在做这样的工作时,人们也必须注意陷阱。

For example, if you have a shared resource consumed by both WorkerA and WorkerB, you will have to do synchronization with any synchronization primitive (such as a Mutex, Semaphore, ManualResetEvent, etc) that is fit for your scenario.

例如,如果您享有WorkerA和WorkerB消耗共享资源,你将不得不做同步与任何同步原语(如MutexSemaphoreManualResetEvent,等),这是适合您的方案。

Also, note that spinning up new threads doesn't come free, there are overheads to each thread such as a 1MB stack for each one created.

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

Note, i'd advise you to look into more modern libraries for doing parallel work such as the Task Parallel Librarythat was introduced in .NET 4.0. Specifically, look into the Taskand Parallelclasses.

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

Edit

编辑

As per your question in the comments, lets see what it looks like to use a Taskvs BackgroundWorker:

根据您在评论中的问题,让我们看看使用Taskvs 的情况BackgroundWorker

BackgroundWorker:

后台工作者:

_worker.WorkerReportsProgress = true;
_worker.WorkerSupportsCancellation = true;
_worker.DoWork += worker_DoWork;
_worker.RunWorkerAsync();

Task:

任务:

var task = Task.Run(worker_DoWork);

or if you're on .NET 4.0:

或者如果您使用的是 .NET 4.0:

var task = Task.Factory.StartNew(worker_DoWork);

You also get the benefits of cancellation, continuation, and the use of async-awaitwith the Taskunit, which makes it far easier to do parallel programming.

您还可以得到的好处取消延续,并采用异步的awaitTask单位,这使得它更容易做到并行编程。

回答by Patrick Hofman

As mentioned before, doing IO simultaneous will not gain you much profit.

如前所述,同时进行 IO 不会为您带来多少利润。

If it is the calculating that is heavy, yes, you could use a BackgroundWorker, or even better a Task(from the Task Parallel Library).

如果计算量很大,是的,您可以使用 a BackgroundWorker,甚至更好的 a Task(来自Task Parallel Library)。

Task t1 = Task.Run( () => HeavyMethod1() );
Task t2 = Task.Run( () => HeavyMethod2() );

await Task.WaitAll(new Task[] {t1, t2});

回答by Dan Dinu

It depends much on what you want to achieve but yes, it is possible to execute them independent one to another, but this does not necessary mean that you will execute them in the same time. (for example if you have single core cpu it's impossible for 2 threads to be scheduled for execution on the CPU at the same time :) ).

这在很大程度上取决于您想要实现的目标,但是是的,可以相互独立地执行它们,但这并不意味着您将同时执行它们。(例如,如果您有单核 cpu,则不可能同时在 CPU 上安排 2 个线程执行 :))。

Creating Threads is a huge performance hit (you can easily see that by yourself, try creating threads in a loop and you'll see :) ). A better idea is to create a ThreadPool Task and let .NET decide if more than one thread is needed to execute your operations (You can start here http://msdn.microsoft.com/en-us/library/0ka9477y(v=vs.110).aspx).

创建线程是一个巨大的性能损失(你可以很容易地自己看到,尝试在循环中创建线程,你会看到:))。一个更好的主意是创建一个 ThreadPool 任务并让 .NET 决定是否需要多个线程来执行您的操作(您可以从这里开始http://msdn.microsoft.com/en-us/library/0ka9477y(v=与 110).aspx)。

EDIT:

编辑:

Check @PatrickHofman answer to see code for creating tasks.

检查@PatrickHofman 答案以查看创建任务的代码。

回答by Sheridan

Have you see the new asynchronous methods that Microsoft added into the .NET Framework in .NET 4.5? While they won't actually read two text files at the exact same time, they will definitely improve the performance of your application. You could use the TextReader.ReadToEndAsyncMethodfor example (taken from the StreamReader.ReadToEndAsyncMethodpage):

你看到微软在 .NET 4.5 中添加到 .NET Framework 中的新异步方法了吗?虽然它们实际上不会完全同时读取两个文本文件,但它们肯定会提高应用程序的性能。例如,您可以使用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);
}

For further information regarding these new asynchronous methods, please see the Asynchronous File I/Opage on MSDN.

有关这些新异步方法的更多信息,请参阅MSDN 上的异步文件 I/O页面。

回答by Andrej Kikelj

You can use TPL to perform parallel calculations. It makes it easy for you to do time consuming work and wait for it to finish. See attached example. You need to use Task.WaitAll() to wait for all tasks to finish, or alternatively, the TPL will wait on all tasks on which you use the .Result property, as in the case below.

您可以使用 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);

回答by Dharani Kumar

Plenty of concepts will allow you to do this,Since you've stressed on executing two method's at once you can go for Multi-threading.Task parallelismalso helps to achieve your goal. If you want more specific answer's just Google "Multi-Threading in .NET". Be cautious Threaded apps are difficult to debug and if not handled correctly may lead to strange results.

很多概念都可以让你做到这一点,因为你强调一次执行两个方法,你可以去多线程。任务并行性也有助于实现您的目标。如果您想要更具体的答案,只需谷歌“.NET 中的多线程”。小心线程应用程序很难调试,如果处理不当可能会导致奇怪的结果。