相关疑难解决方法(0)

LogicalOperationStack与.Net 4.5中的异步不兼容

Trace.CorrelationManager.LogicalOperationStack允许嵌套逻辑操作标识符,其中最常见的情况是日志记录(NDC).它还能用async-await吗?

这是一个简单的例子,使用LogicalFlow它是我的简单包装LogicalOperationStack:

private static void Main() => OuterOperationAsync().GetAwaiter().GetResult();

private static async Task OuterOperationAsync()
{
    Console.WriteLine(LogicalFlow.CurrentOperationId);
    using (LogicalFlow.StartScope())
    {
        Console.WriteLine("\t" + LogicalFlow.CurrentOperationId);
        await InnerOperationAsync();
        Console.WriteLine("\t" + LogicalFlow.CurrentOperationId);
        await InnerOperationAsync();
        Console.WriteLine("\t" + LogicalFlow.CurrentOperationId);
    }
    Console.WriteLine(LogicalFlow.CurrentOperationId);
}

private static async Task InnerOperationAsync()
{
    using (LogicalFlow.StartScope())
    {
        await Task.Delay(100);
    }
}
Run Code Online (Sandbox Code Playgroud)

LogicalFlow:

public static class LogicalFlow
{
    public static Guid CurrentOperationId =>
        Trace.CorrelationManager.LogicalOperationStack.Count > 0
            ? (Guid) Trace.CorrelationManager.LogicalOperationStack.Peek()
            : Guid.Empty;

    public static IDisposable StartScope()
    {
        Trace.CorrelationManager.StartLogicalOperation(); …
Run Code Online (Sandbox Code Playgroud)

.net c# async-await .net-4.5

18
推荐指数
2
解决办法
3316
查看次数

如何使用log4net使用Threadpool线程记录正确的上下文?

我试图找到一种从一堆线程中记录有用上下文的方法.问题是很多代码都是通过线程池线程到达的事件处理的(据我所知),因此它们的名称与任何上下文无关.可以使用以下代码演示此问题:

class Program
{
    private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
    static void Main(string[] args)
    {
        new Thread(TestThis).Start("ThreadA");
        new Thread(TestThis).Start("ThreadB");
        Console.ReadLine();
    }

    private static void TestThis(object name)
    {
        var nameStr = (string)name;
        Thread.CurrentThread.Name = nameStr;
        log4net.ThreadContext.Properties["ThreadContext"] = nameStr;
        log4net.LogicalThreadContext.Properties["LogicalThreadContext"] = nameStr;
        log.Debug("From Thread itself");
        ThreadPool.QueueUserWorkItem(x => log.Debug("From threadpool Thread: " + nameStr));
    }
}
Run Code Online (Sandbox Code Playgroud)

转换模式是:

%date [%thread] %-5level %logger [%property] - %message%newline
Run Code Online (Sandbox Code Playgroud)

输出是这样的:

2010-05-21 15:08:02,357 [ThreadA] DEBUG LogicalContextTest.Program [{LogicalThreadContext=ThreadA, log4net:HostName=xxx, ThreadContext=ThreadA}] - From Thread itself
2010-05-21 15:08:02,357 [ThreadB] DEBUG LogicalContextTest.Program …
Run Code Online (Sandbox Code Playgroud)

c# log4net multithreading threadpool

11
推荐指数
2
解决办法
1万
查看次数

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

在使用任务并行库之前,我经常使用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());
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,通过TPL,我的理解是多个任务共享线程.这是否意味着ActivityId很容易在任务中重新初始化(通过另一项任务)?是否有新的机制来处理活动追踪?

.net c# multithreading task

11
推荐指数
1
解决办法
3046
查看次数

标签 统计

c# ×3

.net ×2

multithreading ×2

.net-4.5 ×1

async-await ×1

log4net ×1

task ×1

threadpool ×1