system.diagnostics.Activity-使用多个线程时,父母/子女关系无效

发布于 2025-01-27 18:31:02 字数 2685 浏览 2 评论 0 原文

我有一个问题,即当另一个线程启动父活动时,主线程将不会看到此活动,而下一个应该是在主线程中创建的儿童活动的活动,我将不会添加到我创建的父活动中在另一个线程中。

我所拥有的:

  1. sytem.diagnostics.activitysource 的静态定义:

      public static ReadOnly activitysource myActivitySource = new ActivitySource(“ myAppName”);
     
  2. 示踪剂提供商的静态定义 opentelemetry.trace.trace.traceprovider

     公共静态TracerProvider TraceProvider;
     
  3. parterActivity的静态定义:

     公共静态活动parentActivity;
     

现在它的工作原理:

  1. 第一个活动是在另一个线程(使用System.Timers.Timer)中创建的,然后在主线程上调用函数。下面的代码仅在未初始化父级时执行一次:

      parentActivity = myActivitySource.startactivity(“ cycleactivity”,ActivityKind.internal);
     parentActivity.Addtag(“ hostName”,emoventir.machinename)
     parentActivity.start();
     mainform.invoke(新操作(()=> initiateProcess()));
     
  2. 然后在 initiateprocess 函数中,我们开始儿童活动 - 一切正常 - 我可以在日志中看到孩子活动活动有父母'从另一个线程在第四步中创建的环节性”。

      public void InitiateProcess()
     {
         使用(var subactivity = global.myactivitysource.startactivity(“ sendingtriggertodevice”))
         {
             subactivity.start();
             devicetcp.send(“触发”);
             subactivity.stop();
         }
     }
     
  3. 问题发生在下一步中,包括等待数据来自 devicetcp 。 我已经定义了回调函数,当 devicetcp 将数据发送到我的应用程序时。 我在该功能内部创建活动,身体看起来像:

      public void devicetcpmessagereceived(字符串数据)
    {
      使用(var subactivity = global.myactivitysource.startactivity(“ devicetcpmessagereceived”))
      {
         subactivity.start();
         // ....其他东西
      }
      parentActivity.stop();
    }
     

在第四步中启动的父活动并没有停止。 我知道 devicetcpmessagereceived 都运行了,一切都很好,除了在回调中创建的活动名为 devicetcpmessagereceived 未连接到父活动。

  1. 总结

任何想法,为什么只有 myActivitySource 才能在主线程上同步调用 InitiateProcess 的呼叫时,为何只能通过 myActivitySource 可见。当来自设备开始的消息和回调函数 devicetcpmessagereceived 在主线程上运行吗?

我已经在文档中阅读了当我开始新的活动时,我可以设置一个ActivityKind:

默认情况下,所有新活动都设置为内部,即 适用于作为内部操作的活动 没有远程父母或孩子的申请。

但是我不知道什么我应该使用。 IMO他们不应影响父母/子女活动之间的关系行为。 (当您查看我描述的4和第五步时,他们显然不这样做)。

同样,从字节线程中的父活动没有关闭(在此期间没有使用或停止调用),直到我们成功地从 devicetcp 中接收数据,所以我不明白为什么在第六次中创建的活动没有父母。

欢迎任何帮助或建议。

I have a problem that when parent activity is started by another thread, then the main thread wont see this activity, and next Activities that supposed to be children activities that are being created in main thread, wont be added to the parent Activity that i created in another thread.

What i have:

  1. Static definition of Sytem.Diagnostics.ActivitySource:

     public static readonly ActivitySource MyActivitySource = new ActivitySource("myAppName");
    
  2. Static definition of tracer provider OpenTelemetry.Trace.TraceProvider:

     public static TracerProvider traceProvider;
    
  3. Static definition of parentActivity:

     public static Activity parentActivity;
    

Now how it works:

  1. First Activity is created in another thread (with use of System.Timers.Timer), and then function is being invoked on main thread. Below code is executed only once- when parentActivity is not initialized:

     parentActivity = MyActivitySource.StartActivity("CycleActivity", ActivityKind.Internal);
     parentActivity.AddTag("hostname", Environment.MachineName)
     parentActivity.Start();
     mainForm.Invoke(new Action(() => initiateProcess()));
    
  2. Then in the initiateProcess function we start child activity- and everything is working fine, i can see in logs that children activity has parent 'CycleActivity' which was created in the 4th step from another thread.

     public void initiateProcess()
     {
         using (var subActivity= global.MyActivitySource.StartActivity("sendingTriggerToDevice"))
         {
             subActivity.Start();
             deviceTcp.Send("Trigger");
             subActivity.Stop();
         }
     }
    
  3. The problem occurs when in the next step, which consist of waiting for the data to come from deviceTcp.
    I have defined callback function, that is being run when deviceTcp send data to my application.
    And im creating activity inside that function and the body looks like:

    public void deviceTcpMessageReceived(string data)
    {
      using (var subActivity = global.MyActivitySource.StartActivity("deviceTcpMessageReceived"))
      {
         subActivity.Start();
         //.... additional stuff
      }
      parentActivity.Stop();
    }
    

Parent activity which has been started in the 4th step is not being stopped in the meantime.
I know that deviceTcpMessageReceived was run, and everything worked fine, except that activity created in callback named deviceTcpMessageReceived was not wired to the parent activity.

  1. Summary

Any ideas, why the parent Activity is only visible by MyActivitySource when i synchronously Invoke a call (from subthread) of initiateProcesson the main thread, and it is not visible, when message from device is comming, and callback function deviceTcpMessageReceived is being ran on the Main thread?

I have read in the documentation System.Diagnostics.Activity that I can set an ActivityKind when i start new Activity that:

By default, all new Activities are set to Internal, which is
appropriate for Activities that are an internal operation within an
application with no remote parent or children.

But i have no idea what Activity Kind i should use. IMO they shouldnt impact relationship behaviour between parent/children activities. (And they clearly dont do it, when you look at 4 and 5th step that i described).

Also the parent activity from the subthread is not closed (there is no using, or Stop being called in the meantime), until we successfully receive data from deviceTcp, so i dont understand why Activity created in the 6th has no parent.

Any help or suggestion is welcome.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半枫 2025-02-03 18:31:02

如果活动不在同一范围内,则可能不会互相连接。
要解决问题,您必须在回调功能中设置父活动。
如果您想将回调事件连接到周期活动,则必须调用SetParentID方法以连接您的回调活动,您的代码看起来像这样:

public void deviceTcpMessageReceived(string data)
{
  using (var subActivity = global.MyActivitySource.StartActivity("deviceTcpMessageReceived"))
  {
     subActivity.SetParentId(parentActivity.TraceId, parentActivity.SpanId);
     subActivity.Start();
     //.... additional stuff
  }
  parentActivity.Stop();
}

If Activities are not in the same scope, they might not wire up to each other.
To solve your problem you have to set up Parent Activity in your callback function.
If you want to wire up callback event to the Cycle Activity you have to call SetParentId method to wire up your callback Activity, your code could look like this:

public void deviceTcpMessageReceived(string data)
{
  using (var subActivity = global.MyActivitySource.StartActivity("deviceTcpMessageReceived"))
  {
     subActivity.SetParentId(parentActivity.TraceId, parentActivity.SpanId);
     subActivity.Start();
     //.... additional stuff
  }
  parentActivity.Stop();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文