我有以下代码:
Task task = null;
var channel = System.Threading.Channels.Channel.CreateUnbounded<string>();
using (var activity = MyActivitySource.StartActivity("Parent"))
{
task = Task.Factory.StartNew(async () =>
{
//Activity.Current = null;
var item = await channel.Reader.ReadAsync();
Console.WriteLine("Task: {0}", Activity.Current?.DisplayName);
});
}
Console.WriteLine("Current end: {0}", Activity.Current?.DisplayName ?? "(null)");
await channel.Writer.WriteAsync("something");
await task;
我想在不注入"活动"的情况下启动该任务。我无法在使用(var acctivity…(之外创建任务。
一个选项(我想(是设置"活动"。当前=任务开始时为null。有其他选择吗?
一个选项(我想(是设置"活动"。当前=任务开始时为null。有其他选择吗?
我的首选解决方案是将";处理";代码转换为单独的顶级循环。也就是说,将当前在StartNew
中的代码移动到一个完全独立的方法中,将其封装在await foreach (var item in channel.Reader.ReadAllAsync())
中,并在启动通道时启动该循环。因此本质上使其成为某种类型的CCD_ 3。
您可能需要使用其他值来增加当前的string
项,以使其发挥作用。也就是说,如果你需要完成每个项目,那么你可以用(string Item, TaskCompletionSource Completion)
代替string
。
还有另一种解决方案可能会起作用(但我确实建议使用顶级循环(:您可以抑制逻辑上下文流(这会抑制所有AsyncLocal
样式的值(。但是,我建议在让任务逃离该块之前,确保任务已经在线程池线程上启动,以防某些代码同步等待。看起来是这样的:
using (var activity = MyActivitySource.StartActivity("Parent"))
{
using var suppressFlow = ExecutionContext.SuppressFlow();
var taskStarted = new TaskCompletionSource(TaskCreationOptions.ExecuteContinuationsAsynchronously);
task = Task.Run(async () =>
{
taskStarted.TrySetResult();
var item = await channel.Reader.ReadAsync();
Console.WriteLine("Task: {0}", Activity.Current?.DisplayName);
});
}
但实际上,我认为;主环路";会更好。