C# 异步运行两个任务

C# 异步运行两个任务,c#,.net,multithreading,asynchronous,async-await,C#,.net,Multithreading,Asynchronous,Async Await,我正在运行一个同步方法。在它里面我必须运行两个大方法,所以我想异步运行它们。。我在想 public void MyFunc() { var doWorkTask_1 = DoWork1(); var doWorkTask_2 = DoWork2(); var result1 = await doWorkTask_1; var result2 = await doWorkTask_2; if(result1 == result2) ...

我正在运行一个同步方法。在它里面我必须运行两个大方法,所以我想异步运行它们。。我在想

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);
}
为此,我需要:

  • DoWork1
    DoWork2
    是异步的
  • 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
    中我有一个
    线程。Sleep
    。我可以让主线程睡眠还是让主线程睡眠更好

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

    使用
    Task.whalll
    创建新任务,封装两个辅助任务

    创建一个任务,该任务将在提供的所有任务完成后完成 完成

    我用两种不同的方式写过同样的东西吗

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

    第二个方法将并行执行两个工作单元,并将同步等待第一个,然后等待第二个

    我可以让主线程睡眠还是让线程睡眠更好 在主楼里面

    这取决于应用程序正在做什么。您可以将
    MyFunc
    设置为
    async
    ,这样您就可以使用
    Task.Delay
    ,它在内部使用计时器并且不会阻塞(如果需要,您还可以传递它):

    旁注:

    在我看来,您可能正在使用async over sync。我建议不要这样做

    相反,与第一个示例中一样,显式调用
    任务。在这些工作线程上运行

    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
    ,异步是指您希望在不同的线程上同时处理
    DoWork1
    DoWork2
    ,然后您可以使用
    任务。运行
    将工作卸载到不同的线程和
    任务。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);
    }
    

    但是您还需要使
    MyFunc
    异步,这显然是OP不希望的do@NedStoyanov我犯错误的频率让编译器开始嘲笑我..你的意思是
    var-doWorkTask_1=新任务(()=>{DoWork1();})??@Gusdor我经常犯同样的错误。所以我想应该弹出一个警告:)你能使
    MyFunc
    async吗?或者它必须是同步的吗?我更喜欢它是同步的,因为如果我执行MyFunc async,我还必须执行调用MyFunc async的方法,等等…我不能在Task.Run中使用匿名函数吗?我如何调用MyFuncAsync???简单的MyFuncAsync();或者Task.Factory.StartNew(MyFuncAsync)?@Ciccio我不知道你的意思。您可以在
    任务中使用匿名func。运行
    。如何调用
    MyFuncAsync
    <代码>等待MyFuncAsync()@Cicco你说得对。这就是为什么async从堆栈的顶部一直到底部。为什么这是个问题?@Ciccio不,你不能。但是你可以使用@Ciccio,那么你就会被阻塞了。这可能会导致僵局。我建议你不要。
    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);
    }
    
    public void MyFunc()
    {
        var task1 = Task.Run(() => DoWork1());
        var result2 = DoWork2();
    
        if (task1.Result == result2)
        {
            // ...
        }
    
        Thread.Sleep(syncInterval);
    }