如何在 C# 中实现线程关联?

     2023-04-12     229

关键词:

【中文标题】如何在 C# 中实现线程关联?【英文标题】:How do I implement thread affinity in C#? 【发布时间】:2017-12-14 22:09:33 【问题描述】:

我有一个需要线程关联的第三方 API。我在我的服务应用程序中使用 WCF 来处理来自客户端的请求,然后将这些请求委托给这个 API。由于 WCF 使用线程池来处理请求,因此我尝试使用以下代码解决此问题(使用 SynchronizationContext 类):

using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Threading;

namespace MyAPIService

  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)]
  public class MyService: IService
  
      ThirdPartyAPI m_api;
      SynchronizationContext m_context;

      MyService()
      
        m_api = new ThirdPartyAPI();
      

      public bool Connect(string ipaddress, int port)
      
        m_context = (SynchronizationContext.Current == null) ? new SynchronizationContext() : SynchronizationContext.Current;
        return m_api.Connect(ipaddress, port);
      

      public bool Disconnect()
      
        throw new NotImplementedException();
      

      public bool IsConnected()
      
        return Send(() => m_api.IsConnected());
      

      public TResult Send<TResult>(Func<TResult> func)
      
        TResult retval = default(TResult);
        m_context.Send(new SendOrPostCallback((x) =>
        
          retval = func();
        )
        , null);
        return retval;
      

  
 

我认为这将允许我在调用 Connect 的同一线程上执行 IsConnected 方法,但从测试来看并非如此。 IsConnected 仍然在池中的任何线程上执行。我做错了什么?

任何帮助将不胜感激。 非常感谢。

【问题讨论】:

您还需要客户端部分的minimal reproducible example,并确保调试代码以了解您获取 MyService 的新实例是否比您预期的更频繁,或者您的同步上下文管理不起作用。 虽然 SynchronizationContext 是适合这项工作的工具,但它也不是魔法。如果您创建一个新的默认同步上下文 (new SynchronizationContext()),它会将工作发布到线程池(这不是您想要的)。您的外部 API(我想它是一个 COM 对象)是否有某种回调方法?如果是这样,则可以在该回调中捕获同步上下文,然后在其他地方重用它。否则,恐怕你得自己写了 @KevinGosse 第三方 API 实际上不是 com 对象。当您说“自己编写”时,您是指我自己的同步上下文吗? @markf78 是的。编写同步上下文来管理单个线程应该不会太困难。事实上,这里和那里可能有一些可用的实现 【参考方案1】:

默认同步上下文在线程池上执行您的工作(因此,您没有线程亲和性)。

如果您想确保工作始终发布到同一个线程,您需要编写自己的同步上下文。例如:

public class SingleThreadSynchronizationContext : SynchronizationContext

    private readonly BlockingCollection<(SendOrPostCallback callback, object state)> _queue;
    private readonly Thread _processingThread;

    public SingleThreadSynchronizationContext()
    
        _queue = new BlockingCollection<(SendOrPostCallback, object)>();
        _processingThread = new Thread(Process)  IsBackground = true ;
        _processingThread.Start();
    

    public override void Send(SendOrPostCallback d, object state)
    
        using (var mutex = new ManualResetEventSlim())
        
            var callback = new SendOrPostCallback(s =>
            
                d(s);
                mutex.Set();
            );

            _queue.Add((callback, state));
            mutex.Wait();
        
    

    public override void Post(SendOrPostCallback d, object state)
    
        _queue.Add((d, state));
    

    public override SynchronizationContext CreateCopy()
    
        return this;
    

    private void Process()
    
        SetSynchronizationContext(this);

        foreach (var item in _queue.GetConsumingEnumerable())
        
            item.callback(item.state);
        
    

请注意,此同步上下文假定回调中未捕获的异常将使进程崩溃。如果不是这种情况(例如,因为您有一个全局异常处理程序),那么您应该添加一些错误处理(在ProcessSend 中)。

【讨论】:

我不得不改变“_queue.Add((d, state));”到“_queue.Add(new WorkItem(d, state));”。此示例是否使用了 C# 7.0 的新功能? 它使用 ValueTuple 是的,您需要添加 nuget 包才能使用它们。如果不想,可以使用“普通”元组:Tuple.Create(s, state)

如何在 C# 中实现 sdbm 哈希函数?

】如何在C#中实现sdbm哈希函数?【英文标题】:HowwouldasdbmhashfunctionbeimplementedinC#?【发布时间】:2010-09-0604:02:53【问题描述】:如何在C#中实现sdbm哈希函数(如this)?【问题讨论】:【参考方案1】:您几乎可以不加改动地获取C... 查看详情

如何在 C# 中实现 ORM

】如何在C#中实现ORM【英文标题】:HowtoimplementanORMinC#【发布时间】:2015-10-3018:34:15【问题描述】:我正在尝试在C#中为MySQL实现我自己的ORM,因为我发现它不能完全按照我的意愿去做。我目前只实现了几个方法(例如保存方法)... 查看详情

如何在c#中实现决策矩阵

】如何在c#中实现决策矩阵【英文标题】:Howtoimplementdecisionmatrixinc#【发布时间】:2013-05-2920:27:33【问题描述】:我需要根据一组相当大的8个相互依赖的条件做出决定。|A|B|C|D|E|F|G|H-----------+---+---+---+---+---+---+---+---Decision01|0|1|-|1|0... 查看详情

java示例代码_UML:如何在Java中实现关联类

java示例代码_UML:如何在Java中实现关联类 查看详情

如何在 C# 中实现 Base64 URL 安全编码?

】如何在C#中实现Base64URL安全编码?【英文标题】:HowtoachieveBase64URLsafeencodinginC#?【发布时间】:2014-12-0819:52:09【问题描述】:我想在C#中实现Base64URL安全编码。在Java中,我们有一个通用的Codec库,它为我提供了一个URL安全编码字... 查看详情

如何在 C# 中实现单例设计模式? [复制]

】如何在C#中实现单例设计模式?[复制]【英文标题】:HowtoimplementsingletondesignpatterninC#?[duplicate]【发布时间】:2014-06-2800:20:24【问题描述】:如何在C#中实现单例设计模式?谁能帮帮我?【问题讨论】:如果你真的需要,请参阅cs... 查看详情

如何在 C# 中实现 3 层架构

】如何在C#中实现3层架构【英文标题】:Howtoimplement3tiersarchitectureinc#【发布时间】:2012-11-2700:23:28【问题描述】:我阅读了很多关于c#中的3层架构的文章,但我看到了:几乎使用业务逻辑层(BLL)作为对象映射数据库中的对应表... 查看详情

如何在 C# 中实现 glob

】如何在C#中实现glob【英文标题】:HowtoimplementglobinC#【发布时间】:2010-09-2818:00:50【问题描述】:我不知道在***上发布您自己的问题答案是否合法,但我看到没有人问过这个问题。我去找了一个C#Glob,但没有找到,所以我写了... 查看详情

在 C# 中实现 runas

...runasinC#【发布时间】:2012-10-0106:16:23【问题描述】:我该如何实施runas/noprofile/netonly/user:@使用C#。System.Diagnostics.ProcessStartInfo具有用户、域、密码、动词(我们可以在其中使用runas)等字段,但如何设置netonly。使用Cmd它不需要令... 查看详情

如何在 C# 中实现 const 正确性? [复制]

】如何在C#中实现const正确性?[复制]【英文标题】:Howtoachieveconst-correctnessinC#?[duplicate]【发布时间】:2008-09-2510:56:07【问题描述】:可能重复:“constcorrectness”inC#我已经编写C++多年,但对C#还很陌生。在学习C#的过程中,我发现... 查看详情

如何在 Python 中实现类似 C# RSACryptoServiceProvider 的加密?

】如何在Python中实现类似C#RSACryptoServiceProvider的加密?【英文标题】:HowtoachieveC#RSACryptoServiceProvider-likeencryptioninPython?【发布时间】:2013-08-0616:49:02【问题描述】:所以,在C#中我有以下代码:publicstaticvoidMain(string[]args)publicKeyXml="... 查看详情

如何在 C# 中实现 YouTrack REST API

】如何在C#中实现YouTrackRESTAPI【英文标题】:HowtoimplementaYouTrackRESTAPIinC#【发布时间】:2011-04-2922:07:18【问题描述】:我想让我的.NetC#程序使用他们的RESTAPI自动创建YouTrack票证。谁能指出我的C#实现或指导我如何去做?【问题讨论... 查看详情

如何使用 C# 在 access 数据库中实现“右外连接”查询?

】如何使用C#在access数据库中实现“右外连接”查询?【英文标题】:Howtoimplement"RightOuterJoin"queryinaccessdatabaseusingC#?【发布时间】:2012-07-2305:12:46【问题描述】:我想编写RightOuterJoin查询以从access数据库中检索数据。如何... 查看详情

如何使用 LINQ 在 C# 中实现梯度下降算法?

】如何使用LINQ在C#中实现梯度下降算法?【英文标题】:HowtoimplementGradientDescentalgorithminC#usingLINQ?【发布时间】:2022-01-0412:46:48【问题描述】:目标是为简单的线性回归创建梯度下降算法。有很多具有多行代码的解决方案。如何... 查看详情

如何使用 c# 在 paypal 中实现 DoDirectPayment

】如何使用c#在paypal中实现DoDirectPayment【英文标题】:HowtoimplementDoDirectPaymentinpaypalusingc#【发布时间】:2013-02-1416:23:33【问题描述】:我是贝宝的新手。我想为我的网站实现直接支付api。意味着当我点击它时我会有一个购买按钮... 查看详情

如何在 C# 中实现交互式决策树

】如何在C#中实现交互式决策树【英文标题】:HowtoimplementaninteractivedecisiontreeinC#【发布时间】:2020-02-0312:58:31【问题描述】:我需要允许用户通过在屏幕上显示的两个简单选项之间进行选择来选择自己的路径,以便进入下一组选... 查看详情

您将如何在 C# 中实现“特征”设计模式?

】您将如何在C#中实现“特征”设计模式?【英文标题】:Howwouldyouimplementa"trait"design-patterninC#?【发布时间】:2012-05-3013:11:21【问题描述】:我知道C#中不存在该功能,但PHP最近添加了一个名为Traits的功能,起初我认为这... 查看详情

如何在excel中实现关联查找?

参考技术A如下:操作设备:戴尔灵越7400操作系统:win10操作软件:2010版excel1、先打开excel,选中需要关联的列,以下图为例,需要将B列的电话关联到E列来,先选中E2单元格。2、在E2单元格中输入公式“=VLOOKUP(D2,$A$2:$B$7,2,0)”。3... 查看详情