如何在另一个线程中继续 TaskCompletionSource<>?
How to continue TaskCompletionSource<> in another thread?
我经常使用 TaskCompletionSource<>
。我有一个网络协议设计,我在一个 tcp/ip 连接中接收许多流。我对这些流进行多路分解,然后通知相应的 "SubConnections" 新内容。
那些 "SubConnections"(正在通过 await
等待)然后应该在一个新线程中继续。
通常我通过将 TaskComplectionSource<>.Set
调用放在匿名 ThreadPool.QueueUserWorkItem
方法中来解决此类问题,如下所示:
ThreadPool.QueueUserWorkItem(delegate { tcs.SetResult(null); });
如果我不这样做,相应的 await tcs.Task
调用将在调用 tcs.SetResult
.
的线程中继续
但是,我知道这不是正确的做事方式。也可以自己编写一个 SynchronizationContext
(或其他东西)来指示 await
调用在另一个线程中继续。
我的主要问题是:我将如何以 "best practice" 方式执行此操作?
我在这里的希望也是避免 ThreadPool
开销,因为与仅阻塞线程并等待 ManualResetEvent
相比,它在 Linux 上相当高 - 即使 SynchronizationContext
(或其他)也可以使用 ThreadPool
.
请不要告诉我在一个 tcp/ip 连接中多路复用某些东西通常是个坏主意,或者我应该只使用 System.IO.Pipelines、REST 或其他。 这是我的场景。谢谢。
您可以使用 TaskCreationOptions.RunContinuationsAsynchronously
(在 .NET 4.6+ 中)创建 TaskCompletionSource
:
var tcs = new TaskCompletionSource<Result>(TaskCreationOptions.RunContinuationsAsynchronously);
...
tcs.SetResult(...);
参见例如了解更多详情。
我经常使用 TaskCompletionSource<>
。我有一个网络协议设计,我在一个 tcp/ip 连接中接收许多流。我对这些流进行多路分解,然后通知相应的 "SubConnections" 新内容。
那些 "SubConnections"(正在通过 await
等待)然后应该在一个新线程中继续。
通常我通过将 TaskComplectionSource<>.Set
调用放在匿名 ThreadPool.QueueUserWorkItem
方法中来解决此类问题,如下所示:
ThreadPool.QueueUserWorkItem(delegate { tcs.SetResult(null); });
如果我不这样做,相应的 await tcs.Task
调用将在调用 tcs.SetResult
.
但是,我知道这不是正确的做事方式。也可以自己编写一个 SynchronizationContext
(或其他东西)来指示 await
调用在另一个线程中继续。
我的主要问题是:我将如何以 "best practice" 方式执行此操作?
我在这里的希望也是避免 ThreadPool
开销,因为与仅阻塞线程并等待 ManualResetEvent
相比,它在 Linux 上相当高 - 即使 SynchronizationContext
(或其他)也可以使用 ThreadPool
.
请不要告诉我在一个 tcp/ip 连接中多路复用某些东西通常是个坏主意,或者我应该只使用 System.IO.Pipelines、REST 或其他。 这是我的场景。谢谢。
您可以使用 TaskCreationOptions.RunContinuationsAsynchronously
(在 .NET 4.6+ 中)创建 TaskCompletionSource
:
var tcs = new TaskCompletionSource<Result>(TaskCreationOptions.RunContinuationsAsynchronously);
...
tcs.SetResult(...);
参见例如