好的,我希望我掌握了异步/等待的基础知识,但仍然有一些疑问在我脑海中徘徊。

但是现在这是我在说的问题。假设在这个简单的例子中

static void Main(string[] args)
{

    Method();

    Console.WriteLine("Main Thread");

    Console.ReadLine();

}

public async static void Method()

{

    await Task.Run(new Action(LongTask));

    Console.WriteLine("New Thread");

}

public static void LongTask()

{

    Thread.Sleep(8000);

    Console.WriteLine("Long Task");

}

调用Method()并等待8秒后,主线程仍然继续并打印Main Thread

因此相应地,Method()返回到调用者,即返回到主函数,一旦遇到等待,保存同步上下文并从那里继续执行。

它首先打印Main Thread

然后在8秒钟后完成,先打印Long Task,再打印New Thread

这部分我明白了。我的问题在我的申请中:
public IList<createcaseoutput> createCase(CreateCaseInput CreateCaseInput,SaveCaseSearchInput SaveCaseSearchInput)
{
    .............
    SQL.CaseSQL.getCreateCaseParameters(CreateCaseInput, out strSPQuery, out listParam);
    var AcctLst = rep.ExecuteStoredProcedure<createcaseoutput>(strSPQuery, listParam).ToList();

    if (!string.IsNullOrEmpty(AcctLst.ElementAt(0).o_case_seq.ToString()))

    {
        await saveCaseSearch(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);
    }

    console.writeline("Async called");
    return AcctLst;
}

public async Task<ilist<savecasesearchoutput>> saveCaseSearch(SaveCaseSearchInput SaveCaseSearchInput,Int64? case_key)

{
    ..........................
    SQL.CaseSQL.getSaveCaseSearchParameters(SaveCaseSearchInput, case_key, out strSPQuery, out listParam);

    var AcctLst = await rep.ExecuteStoredProcedureAsync<entities.case.savecasesearchoutput>(strSPQuery, listParam);

    return AcctLst;
}

在这里createCase也遇到了等待和
它应该立即返回并执行自身的下一行,并打印Async called甚至在SaveCaseSearch完成之前就可以了吗?

好吧,如果我想的话,可能是control returns to the caller

这是否就像我将调用SavCaseSearch包装在另一个名为suppose的async/await方法中一样
async DoWork() {....
}

并直接从DoWork()调用此CreateCase(),然后
It will go on printing "Async called" once call to DoWork() encounters await and before it even completes ?
我在以正确的方式思考吗?

有时候我也看到之间有些困惑
await someAsync()


await Task.Run(() => someAsync()) ..

它们之间有什么区别?以及哪个跟随?

最佳答案



您的代码无法编译,因为您使用的是await而不是async。更正后的代码为:

public async Task<IList<createcaseoutput>> createCaseAsync(CreateCaseInput CreateCaseInput,SaveCaseSearchInput SaveCaseSearchInput)
{
  ...
  await saveCaseSearch(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);
  console.writeline("Async called");
  return AcctLst;
}



否。此代码:
  await saveCaseSearch(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);

与此代码相同:
  var saveTask = saveCaseSearchAsync(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);
  await saveTask;

因此,首先,createCaseAsync将调用saveCaseSearchAsync。大概saveCaseSearchAsync正在执行一些异步操作,因此它将返回一个不完整的任务到createCaseAsynccreateCaseAsync然后await那个任务,这导致它向其调用者返回一个不完整的任务。

最终,saveCaseSearchAsync将完成,这将完成它返回的任务(我在上面的代码中将其称为saveTask)。反过来,这将继续执行createCaseAsync,并将继续进行到下一行并在控制台上打印“Async named”。



您不需要包装器,因为createCaseAsync已经返回了Task


Task.Run主要用于将阻塞工作从UI线程推送到线程池。由于您使用的是ASP.NET,因此请不要使用Task.Run

关于c# - 异步/等待VS Task.Run : When to use ?如何使用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36653926/

10-11 22:40
查看更多