运行 两个任务异步

Run two task asynchronously

我正在 运行 使用同步方法。在里面我必须 运行 两个大方法,所以我想 运行 他们异步..我在想

public void MyFunc()
{
    var doWorkTask_1 = DoWork1();
    var doWorkTask_2 = DoWork2();

    var result1 = await doWorkTask_1;
    var result2 = await doWorkTask_2;

    if(result1 == result2) 
       ....

    Thread.Sleep(syncInterval);
}

为此我需要:

  1. DoWork1DoWork2是异步的;
  2. MyFunc也是异步的;

但是没有方法是异步的!!!

所以我尝试了另一种方式:

public void MyFunc()
{
    var doWorkTask_1 = Task.Run(() => DoWork1());
    var doWorkTask_2 = Task.Run(() => DoWork2());

    var result1 = doWorkTask_1.Result;
    var result2 = doWorkTask_2.Result;

    if(result1 == result2) 
       ....

    Thread.Sleep(syncInterval);
}

那么,第一个问题: 我用两种不同的方式写了同样的东西吗?

第二题。我必须每 X 次 运行 MyFunc 方法,所以我这样调用它:

Task.Factory.StartNew(MyFunc);

我可以简单地称呼它吗

MyFunc();

我的问题是因为在 myFunc 里面我有一个 Thread.Sleep。我可以让主线程休眠还是让主线程休眠更好?

希望我已经说清楚了。 谢谢。

使用 Task.WhenAll 创建一个新任务,封装您的两个工作任务。

Creates a task that will complete when all of the supplied tasks have completed.

https://msdn.microsoft.com/en-us/library/hh194874%28v=vs.110%29.aspx

public async void MyFunc()
{
    var doWorkTask_1 = DoWork1();
    var doWorkTask_2 = DoWork2();

    var results = await Task.WhenAll(doWorkTask_1, doWorkTask_2);
}

Have I written same thing in two different ways?

没有。您的第一个方法将 并行 执行两个工作单元,并将 异步等待 第一个,然后是第二个。

您的第二种方法将并行执行两个工作单元,并且同步等待第一个,然后是第二个一.

Can I let sleep the main thread or is better to let sleep a thread inside the main?

这取决于您的应用程序在做什么。你可以把 MyFunc 变成 async 这样你就可以使用 Task.Delay 来代替,它在内部使用 timer 并且不会阻塞(你可以如果需要,也可以传递 CancellationToken):

public async Task MyFuncAsync()
{
   // Do work

   await Task.Delay(syncInterval);
}

旁注:

在我看来,您可能正在使用 异步优于同步which in general is a questionable approach。我会反对它。

相反,就像在您的第一个示例中一样,对这些工作人员显式调用 Task.Run

public async Task MyFuncAsync()
{
    var firstTask = Task.Run(() => DoWork1());
    var secondTask = Task.Run(() => DoWork2());

    await Task.WhenAll(new[] { firstTask, secondTask });
    await Task.Delay(syncInterval);
}

如果你不能一直做 async,异步意味着你想在不同的线程上同时处理 DoWork1DoWork2 那么你可以使用 Task.Run 将工作卸载到不同的线程并 Task.WaitAll 等待 同步 两个任务完成:

public void MyFunc()
{
    var task1 = Task.Run(() => DoWork1());
    var task2 = Task.Run(() => DoWork2());

    Task.WaitAll(task1, task2);
    if (task1.Result == task2.Result)
    {
        // ...
    }

    Thread.Sleep(syncInterval);
}

现在,由于这使用了 3 个线程(Task.Run 中有两个 ThreadPool 线程,调用线程阻塞在 Task.WaitAll 上),而我们只需要 2 个线程,我们可以简化和优化示例通过在调用线程上执行操作之一:

public void MyFunc()
{
    var task1 = Task.Run(() => DoWork1());
    var result2 = DoWork2();

    if (task1.Result == result2)
    {
        // ...
    }

    Thread.Sleep(syncInterval);
}