C# 异步/等待vs任务。在C中运行#
我刚刚接触过这个异步的世界。C# 异步/等待vs任务。在C中运行#,c#,.net,multithreading,asynchronous,C#,.net,Multithreading,Asynchronous,我刚刚接触过这个异步的世界。 请容忍我缺乏知识 据说当一种方法遇到等待。。。“它告诉等待者在完成时运行方法的其余部分,然后从异步方法返回。” 我没有得到这个部分。 那么,这是否意味着该方法仍在同步运行,等待等待返回,然后继续执行该方法的其余部分? 如果没有,请解释为什么需要Task.Run在后台或以触发并忘记方式运行方法。我仍然可以通过等待来实现,对吗?i、 e. 该方法继续执行其余语句,而不等待等待返回。 我希望这类似于后台运行方法。或者不是吗?我很困惑 如果一个方法标记为async和awai
请容忍我缺乏知识
我没有得到这个部分。
那么,这是否意味着该方法仍在同步运行,等待等待返回,然后继续执行该方法的其余部分?
如果没有,请解释为什么需要
Task.Run
在后台或以触发并忘记方式运行方法。我仍然可以通过等待来实现,对吗?i、 e.该方法继续执行其余语句,而不等待等待返回。
我希望这类似于后台运行方法。或者不是吗?我很困惑
那么,第一个标记为async并从单独的方法等待的方法的调用名称ABC应该是什么样子的?
我不想将该方法注释为async/await。所以
Task.Run(() => DoWork());
从ABC()可以,但不标记为异步/等待?还是违反了异步原则
public IList<CreateCaseOutput> ABC(CreateCaseInput CreateCaseInput,SaveCaseSearchInput SaveCaseSearchInput)
{
CaseSQL.getABCParameters(CreateCaseInput, RequestType, out strSPQuery, out listParam);
var AcctLst = rep.ExecuteStoredProcedure<CreateCaseOutput>(strSPQuery, listParam).ToList();
if (!string.IsNullOrEmpty(AcctLst.ElementAt(0).o_case_seq.ToString()))
{
Task.Run(async () =>
{
await DEF(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);
}).ConfigureAwait(false);
}
console.writeLine("After Async called");
return AcctLst;
}
public async Task<SaveCaseSearchOutput>> DEF(SaveCaseSearchInput SaveCaseSearchInput,Int64? case_key)
{
CaseSQL.getDEFParameters(SaveCaseSearchInput, case_key, out strSPQuery, out listParam);
var AcctLst = await rep.ExecuteStoredProcedureAsync<SaveCaseSearchOutput>(strSPQuery, listParam);
return AcctLst;
}
而不是
Task.Run(async () =>
{
await DEF(SaveCaseSearchInput, AcctLst.ElementAt(0).o_case_seq);
}).ConfigureAwait(false);
}
return AcctLst;
然后,此代码在调试器中同步运行
我做错什么了吗?'。。。“它告诉等待者在完成时运行方法的其余部分,然后从异步方法返回。”'
假设您有一个调用方法B的方法a。方法B的声明中有“async”关键字。在方法B中,对LongMethod有一个耗时的调用,它最终返回一个字符串
这里我们想要的是方法A不必等待方法B的LongMethod完成。因此,我们在方法B中写道:
string newVariable=wait Task.Run(()=>LongMethod())代码>
如果LongMethod本身也是异步的,那么LongMethod只能返回void、非泛型任务或泛型任务。因此,我们必须将LongMethod声明中的返回类型更改为Task
回到我们的故事,LongMethod任务已经开始。。。此时,方法A从调用方法B后的下一行代码恢复,方法B继续等待LongMethod完成,因此现在有两个线程正在运行。最终,LongMethod完成,方法B运行到最后,同时方法A继续运行,甚至可能已经完成运行
我希望这能让您了解异步/等待和任务之间的关系
现在回答问题2:
我认为您的问题基本上是问我的示例中的方法A是否需要标记为“async”,因为它调用标记为“async”的方法,而不是。另外请注意,ABC()只需要
DoWork()
不
Task.Run(()=>DoWork())代码>
然后,ABC将停止运行,直到DoWork方法到达“await”语句
如果DoWork只需要作为自己的任务运行,而您根本不希望ABC()停止,那么就这样做吧
Task.Run(()=>DoWork())代码>
在这种情况下,将DoWork标记为async没有任何好处,因为在DoWork中没有任何等待语句
我希望这能有所帮助,如果我误解了你的问题,请原谅
那么,这是否意味着该方法仍然保持同步运行,等待等待的返回,然后继续执行该方法的其余部分
不是。等待有一个“回调”机制。因此,该方法只是将其自身注册到等待中。当等待完成时,它将执行回调,其中包括async
方法的延续
同时,async
方法返回一个未完成的任务
如果没有,请解释为什么需要Task.Run在后台或以fire and forget方式运行方法
如果要在后台线程上运行,请使用Task.run
<代码>任务。运行
仅将工作安排到线程池
我仍然可以通过等待来实现,对吗?即
该方法继续执行其余语句,而不等待wait返回。
我希望这类似于后台运行方法。或者不是吗?我很困惑
好吧,你可以通过不等待来“忘记”任务:
MyMethod()
{
SomeMethodAsync(); // Note: no await; we just ignore the task.
}
不过,你几乎从来都不想做“开火然后忘记”。很容易>90%的人要求它,这实际上是一个设计错误
我不想将该方法注释为async/await。。。还是违反了异步原则
那是违反原则的。如果您仔细想想,阻塞异步代码是没有意义的。您希望经历使方法异步(意味着它不阻塞线程)的麻烦,然后在其上阻塞线程吗?为什么呢?有时在实践中,代码在转换到异步代码时会暂时处于这种状态,但这是一个棘手的问题
有关更多信息,请参阅我在上的文章,特别是“一路异步”。来自您在评论中所说的内容(我假设您需要ABC中的结果)
你只需要写
Task t=Task.Run(()=>DEF(SaveCaseSearchInput,AcctLst.ElementAt(0.o_case_seq))代码>
在ABC中,而不是当前任务。运行调用
然后在ABC中的行中,当您需要写入结果时
t.Wait()
SaveCaseSearchOutput g=t.结果代码>
DEF必须保持异步,但您可以删除DEF中的WAIT语句。我想解释一下,但它已经很简单了,看看这是否有助于解决问题
MyMethod()
{
SomeMethodAsync(); // Note: no await; we just ignore the task.
}