好的,我希望我掌握了异步/等待的基础知识,但仍然有一些疑问在我脑海中徘徊。
但是现在这是我在说的问题。假设在这个简单的例子中
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
正在执行一些异步操作,因此它将返回一个不完整的任务到createCaseAsync
。 createCaseAsync
然后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/