简体   繁体   English

C#异步调用“调用并忘记”

[英]C# Asynchronous call “invoke and forget”

In c# when you invoke the await method inside an async method, the code will be executed from the calling context to that method. 在c#中,当您在异步方法中调用await方法时,代码将从调用上下文执行到该方法。 What if I want to make an asynchronous call which will just continue from the same line of code directly (even if the asynchronous action did not finish yet) instead of getting back to the calling context? 如果我要进行一个异步调用,而该异步调用将直接从同一行代码直接继续(即使异步操作尚未完成),而不是返回到调用上下文,该怎么办? How can I do that? 我怎样才能做到这一点?

An await is, by definition, a point at which you must asynchronously wait for the task to finish before continuing the workflow. 根据定义,等待是必须继续执行工作流之前必须异步等待任务完成的时间。 If you don't have to wait, then don't wait! 如果您不必等待,那就不要等待! There is no requirement that you await anything. 不需要您等待任何事情。

Your question is rather like asking "I have an IEnumerable<int> but I don't care what integers are in it; do I have to foreach over it?" 您的问题就像是问“我有IEnumerable<int>但我不在乎其中有什么整数;我是否必须foreach它?” No, you don't. 不,你没有。 If you don't care what the result is, you don't have to get a result from a sequence. 如果您不在乎结果是什么,则不必从序列中获取结果。 If you don't care what the result of a task is, you don't have to await it. 如果您不关心任务的结果是什么,则不必等待任务。

But it is a strange thing to get a sequence and then not enumerate it, and it is a strange thing to get a task and then not care about what happens when it completes. 但是获得一个序列然后不枚举它是一件很奇怪的事情,而获得一个任务然后又不在乎它完成时会发生什么是一件很奇怪的事情。

What if I want to make an asynchronous call which will just continue from the same line of code directly (even if the asynchronous action did not finish yet) instead of getting back to the calling context? 如果我要进行一个异步调用,而该异步调用将直接从同一行代码直接继续(即使异步操作尚未完成),而不是返回到调用上下文,该怎么办? How can I do that? 我怎样才能做到这一点?

The easiest way, which works whether Something is synchronous or asynchronous: 最简单的方法,不管Something是同步的还是异步的,它都可以工作:

var _ = Task.Run(() => Something());

But, as Eric Lippert stated: 但是,正如埃里克·利珀特(Eric Lippert)所说:

it is a strange thing to get a task and then not care about what happens when it completes. 得到任务然后不关心完成时会发生什么是一件奇怪的事。

Or, as I like to put it: fire-and-forget is almost never what you really want. 或者,就像我喜欢说的那样:“一劳永逸” 几乎不是您真正想要的。 To "forget" means: “忘记”是指:

  1. You don't care when it completes. 您不在乎它何时完成。
  2. You don't care whether it completes. 您不在乎它是否完成。 Eg, if your app exits (or app pool is recycled if on ASP.NET), then your background work is just lost. 例如,如果您的应用程序退出(或者如果在ASP.NET上应用程序池被回收),那么您的后台工作就会丢失。
  3. You don't care whether it completes successfully . 您不在乎它是否成功完成。 Eg, if your work throws an exception, you want to silently swallow that exception. 例如,如果您的工作引发异常,则您静默地吞下该异常。

In real-world code, this scenario is extremely rare. 在实际代码中,这种情况极为罕见。

If you want to start the async method and continue inside the function you can do something like Task<string> getStringTask = asyncMethodThatReturnsString(); 如果要启动异步方法并在函数内部继续,则可以执行Task<string> getStringTask = asyncMethodThatReturnsString(); . Then continue until you want to wait for the async task to finish at which point you would call string output = await getStringTask; 然后继续,直到您要等待异步任务完成为止,此时将调用string output = await getStringTask; .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM