gpt4 book ai didi

c# - 任务并行库中的任务如何影响ActivityID?

转载 作者:可可西里 更新时间:2023-11-01 08:45:45 25 4
gpt4 key购买 nike

在使用任务并行库之前,我经常使用 CorrelationManager.ActivityId 来跟踪多线程的跟踪/错误报告。

ActivityId 存储在线程本地存储中,因此每个线程都有自己的副本。这个想法是,当你启动一个线程(事件)时,你分配一个新的 ActivityId。 ActivityId 将与任何其他跟踪信息一起写入日志,从而可以为单个“事件”挑出跟踪信息。这对于 WCF 非常有用,因为 ActivityId 可以转移到服务组件。

这是我正在谈论的例子:

static void Main(string[] args)
{
ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
{
DoWork();
}));
}

static void DoWork()
{
try
{
Trace.CorrelationManager.ActivityId = Guid.NewGuid();
//The functions below contain tracing which logs the ActivityID.
CallFunction1();
CallFunction2();
CallFunction3();
}
catch (Exception ex)
{
Trace.Write(Trace.CorrelationManager.ActivityId + " " + ex.ToString());
}
}

现在,对于 TPL,我的理解是多个任务共享线程。这是否意味着 ActivityId 很容易在任务中(由另一个任务)重新初始化?有没有新的机制来处理事件追踪?

最佳答案

我进行了一些实验,结果证明我的问题中的假设是不正确的 - 使用 TPL 创建的多个任务不会同时在同一个线程上运行。

ThreadLocalStorage 可以安全地与 .NET 4.0 中的 TPL 一起使用,因为一个线程一次只能由一个任务使用。

任务可以并发共享线程的假设是基于我在 DotNetRocks 上听到的关于 c# 5.0 的采访。 (抱歉,我不记得是哪个节目了)- 所以我的问题可能(也可能不)很快变得相关。

我的实验启动了多个任务,记录了运行了多少个任务,耗时多少,消耗了多少线程。代码如下,如果有人想重复的话。

class Program
{
static void Main(string[] args)
{
int totalThreads = 100;
TaskCreationOptions taskCreationOpt = TaskCreationOptions.None;
Task task = null;
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Task[] allTasks = new Task[totalThreads];
for (int i = 0; i < totalThreads; i++)
{
task = Task.Factory.StartNew(() =>
{
DoLongRunningWork();
}, taskCreationOpt);

allTasks[i] = task;
}

Task.WaitAll(allTasks);
stopwatch.Stop();

Console.WriteLine(String.Format("Completed {0} tasks in {1} milliseconds", totalThreads, stopwatch.ElapsedMilliseconds));
Console.WriteLine(String.Format("Used {0} threads", threadIds.Count));
Console.ReadKey();
}


private static List<int> threadIds = new List<int>();
private static object locker = new object();
private static void DoLongRunningWork()
{
lock (locker)
{
//Keep a record of the managed thread used.
if (!threadIds.Contains(Thread.CurrentThread.ManagedThreadId))
threadIds.Add(Thread.CurrentThread.ManagedThreadId);
}
Guid g1 = Guid.NewGuid();
Trace.CorrelationManager.ActivityId = g1;
Thread.Sleep(3000);
Guid g2 = Trace.CorrelationManager.ActivityId;
Debug.Assert(g1.Equals(g2));
}
}

输出(当然这取决于机器)是:

Completed 100 tasks in 23097 milliseconds
Used 23 threads

将 taskCreationOpt 更改为 TaskCreationOptions.LongRunning 会得到不同的结果:

Completed 100 tasks in 3458 milliseconds 
Used 100 threads

关于c# - 任务并行库中的任务如何影响ActivityID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4340948/

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