gpt4 book ai didi

c# - 配置 TaskCompletionSource 的任务的延续行为

转载 作者:太空狗 更新时间:2023-10-30 00:05:23 26 4
gpt4 key购买 nike

考虑以下代码:

public Task SomeAsyncMethod()
{
var tcs = new TaskCompletionSource();
... do something, NOT setting the TaskCompletionSource...

return tcs.Task
}

public void Callsite1()
{
await SomeAsyncMethod();
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
}

public void Callsite2()
{
SomeAsyncMethod().ContinueWith((task) =>
{
Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
});
}

在某个时间点,在 SomeAsyncMethod 中创建的 TaskCompletionSource 被设置在 ThreadPool 线程上:

Debug.WriteLine(Thread.CurrentThread.ManagedThreadId);
tcs.SetResult();

当等待来自 TaskCompletionSource 的任务时(如在 Callsite1 中),继续在调用 SetResult 的线程上同步执行。当调用 ContinueWith 时(如在 Callsite2 中),继续在不同的线程上异步执行。

调用configure await没有帮助,如

public void Callsite1()
{
await SomeAsyncMethod().ConfigureAwait(true or false);
}

这甚至不是这个问题的重点。作为 SomeAsyncMethod 的实现者,我不想通过调用 SetResult 来调用一些潜在的未知代码。我想让延续始终异步安排。而且我不能依赖调用者正确配置 await(如果这样可行的话)。

如何配置 TaskCompletionSource,使其 Task 在等待时不同步执行其延续?

最佳答案

没有办法阻止同步任务继续。通常,这不是问题。

但是,在某些情况下您确实需要这样做,例如,如果您在持有锁的同时完成任务。在这些情况下,您可以只Task.Run 完成任务,如下所示:

// Set the result on a threadpool thread, so any synchronous continuations
// will execute in the background.
Task.Run(() => tcs.TrySetResult(result));

// Wait for the TCS task to complete; note that the continuations
// may not be complete.
tcs.Task.Wait();

这是一项高级技术。这是一个异常(exception) guideline "Don't block on async code (async all the way down)" as expounded on my blog .

这是我的一部分 AsyncEx library ,作为扩展方法:

public static void TrySetResultWithBackgroundContinuations<TResult>(
this TaskCompletionSource<TResult> @this, TResult result);

这项技术是 first published by Stephen Toub on his blog .

关于c# - 配置 TaskCompletionSource 的任务的延续行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12693046/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com