如何在不运行异步方法的情况下排队异步方法的任务结果?
简短的回答:你做不到 . 调用 async 方法会执行该方法 . 它必然会开始运行 . 如果您希望能够推迟呼叫,则需要将其包装在可以执行此操作的内容中 .
一个例子可能是 Func> ,除了您设计与我们分享的一小部分代码表明您希望能够返回一个承诺( Task )以及代表此调用的'll make in the future. You can wrap the whole thing in another task, like in your example code, but IMHO that'一个非常严厉的方法,因为它绑定(并可能创建新的)线程池线程只是为了调用 async 方法 .
一个更好的方法(恕我直言)来实现这一点是使用 TaskCompletionSource . 您可以将 Func 存储在队列中,该队列使用返回值来设置 TaskCompletionSource ,然后当您决定可以启动任务时,调用 Func .
就像是:
public Task ExecuteAsync(T transaction) {
if (mustDelay) {
TaskCompletionSource tcs = new TaskCompletionSource();
enqueue(async () =>
{
tcs.SetValue(await executeAsync(transaction));
});
return tcs.Task;
}
return executeAsync(transaction);
}
请注意,这里 ExecuteAsync() 不需要 async . 你要么返回 TaskCompletionSource 的任务,要么返回 executeAsync() 方法返回的任务(顺便说一下,有两个名字只在字母大小不同的方法是恕我直言的想法) .
另请注意,您的队列将存储 Func 个对象,甚至可能存在 Action 个对象(它通常不赞成 async void 方法,例如上面的匿名方法,但是你没有发现它在这种情况下工作正常) . 当您将项目出列时,您将调用该委托 . 根据您的需要,这将是"fire-and-forget"(如果您存储 Action 委托)或者取消和调用委托的方法可能等待委托的返回值(如果您正在存储 Func 委托) .
不幸的是,你的问题相当含糊 . 所以不可能提供比这更多的东西 . 如果您需要其他帮助,请改进问题,以便它包含一个好的Minimal, Complete, and Verifiable code example,清楚地显示您在解决问题时遇到的问题,以及详细描述的适当解释 .