【问题标题】:How to group data logging in multithreading?如何在多线程中对数据记录进行分组?
【发布时间】:2016-06-25 13:19:26
【问题描述】:

我有两种方法。一种方法包含 ThreadPool,而 ThreadPool 运行第二种方法。
代码如下:sn-p:

    static void Main()
    {
        var processes = GetProcessCounter();

        foreach (var process in processes)
        {
            var tmp = process;
            ThreadPool.QueueUserWorkItem(WriteCounter, tmp); 
            Console.Write("\n\n");
        }

        Console.WriteLine("Any key to exit...");
        Console.Read();
    }

    static void WriteCounter(object obj)
    {
        var process = (ProcessInstance) obj;
        Console.WriteLine(
            $"Thread ID: {Thread.CurrentThread.ManagedThreadId}, " +
            $"Process Name: {process.ProcessName}, " +
            $"Process ID {process.ProcessId} ");
        Console.Write("\n");

        foreach (var cnt in process.Counters)
        {
            cnt.NextValue();
            Console.WriteLine(
                $"ThreadId: {Thread.CurrentThread.ManagedThreadId} | " +
                $"Group: {cnt.CategoryName} | " +
                $"Process: {cnt.InstanceName} | " +
                $"Name: {cnt.CounterName} | " +
                $"Value: {cnt.GetCalculatedValue(cnt.CounterName)}");

            cnt.Close();
        }
    }

我看到它工作正常。正如我计算的那样,子循环将与父循环在一个线程中运行。但是在控制台中我看到了folowins。全部混合:

线程 ID:15,进程名称:SearchFilterHost,进程 ID 1552

线程 ID:12 |组: 过程 |进程:资源管理器 |名称:% 用户时间 |值:0
线程 ID:13 |组: 过程 |进程:mqsvc |名称:% 用户时间 |值:0
线程 ID:14 |组: 过程 |进程:SearchProtocolHost |名称:% 处理器时间 |值:0
线程 ID:4 |组: 过程 |进程:RtWLan |名称:% 特权时间 |值:0,599904
ThreadId:15 |组: 过程 |进程:SearchFilterHost |名称:% 处理器时间 |值:0
线程 ID:11 |组: 过程 |进程:VsHub |名称:% 特权时间 |值:0
线程 ID:16,进程名称:AAM 更新通知程序,进程 ID 1280

线程 ID:12 |组: 过程 |进程:资源管理器 |名称:% 特权时间 |值:0,142615
ThreadId:15 |组: 过程 |进程:SearchFilterHost |名称:% 用户时间 |值:0
线程 ID:14 |组: 过程 |进程:SearchProtocolHost |名称:% 用户时间 |值:0
线程 ID:13 |组: 过程 |进程:mqsvc |名称:% 特权时间 |值:0
线程 ID:4 |组: 过程 |进程:RtWLan |名称:虚拟字节峰值 |价值:1,957683E+08
线程 ID:16 |组: 过程 |流程:AAM 更新通知程序 |名称:% 处理器时间 |值:0

按 ThreadID 分组输出应该怎么做?

【问题讨论】:

    标签: c# multithreading threadpool


    【解决方案1】:

    你有几个选择:

    1. 每个线程只使用一次Console.WriteLineConsole.WriteLinethread-safe,所以如果你使用线程到build your output string 并在最后调用Console.WriteLine 就足够了。
    2. 在所有Console.WriteLine 调用中明确使用一些thread-synchronization construct - 例如lock (consoleLock) { Console.WriteLine(...); for (...) Console.WriteLine(...)}。尽管一次构建整个输出字符串(如上一个选项中所述)是一个更好的主意 - 您应该锁定 尽可能短的时间间隔,因为如果您将整个线程启动委托锁定它会赢' 不会比单线程解决方案快多少,而且有很多线程池线程在等待共享资源,从性能的角度来看,它会 be unwise and even harmful
    3. 如果你想做一些更高级的事情,那么你可以尝试一些consumer-producer 实现(如Synchronizing events from different threads in console application),其中只有一个线程从其他线程写入消息。它与选项 1 和 2 没有太大区别,因为它仍然是 WriteCounter 的责任,只发送一次数据,所以
    4. 如果您想进一步过度设计它,您可以将消费者生产者与per-thread 缓冲结合起来

      public interface IBatchTextWriter : 
      {
          TextWriter TextWriter { get; }
          /// <summary>
          /// Ends the batch (everything written to the <see cref="TextWriter"> will be written to the actual stream).
          void EndBatch();
      }
      

      并像这样使用它:

      var process = (ProcessInstance) obj;
      batchWriter.TextWriter.WriteLine(
          $"Thread ID: {Thread.CurrentThread.ManagedThreadId}, " +
          $"Process Name: {process.ProcessName}, " +
          $"Process ID {process.ProcessId} ");
      batchWriter.TextWriter.Write("\n");
      
      foreach (var cnt in process.Counters)
      {
          cnt.NextValue();
          batchWriter.TextWriter.WriteLine(
              $"ThreadId: {Thread.CurrentThread.ManagedThreadId} | " +
              $"Group: {cnt.CategoryName} | " +
              $"Process: {cnt.InstanceName} | " +
              $"Name: {cnt.CounterName} | " +
              $"Value: {cnt.GetCalculatedValue(cnt.CounterName)}");
      
          cnt.Close();
      }
      
      batchWriter.EndBatch();
      

    P.S.: 推荐阅读有关 ThreadPool 和任务 - C# - ThreadPool vs Tasks

    【讨论】:

      猜你喜欢
      • 2015-02-18
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-28
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      相关资源
      最近更新 更多