WCF服务器(net-tcp)反对回退并运行非线程安全的非托管代码

时间:2011-09-08 19:16:03

标签: multithreading wcf multiprocessing

我的任务是为现有的(会话满的)服务编写WCF服务主机(服务器) - 到目前为止并不难。该服务是一个ADO代理服务器,它代理ADO与各种后端数据库的连接。这在大多数情况下运行良好,但我需要支持的一个ADO .NET数据提供程序是作为连接到非线程安全的非托管代码(C)API的驱动程序实现的。

首选解决方案,使代码线程安全或实现线程安全的托管驱动程序现在不在桌面上。有人建议我可以将多个进程作为一种后端或二级代理进行旋转,但是当我第一次听到它时,这让我感到噩梦,甚至在我试用实现时也是如此。

我的问题是,我在这里缺少另一种解决方案吗?到目前为止,我已经玩过ConncurrencyMode.Single和UseSynchronization = true,但事情的真正核心是sessionfull并且具有非线程安全的后端。到目前为止没有运气。我是否坚持代理连接到多个进程,或者其他人可以提出更优雅的解决方案吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我会做什么(实际上我自己一直处于这种情况)就是启动一个专用线程来处理分派给非托管API的请求。线程将坐在那里等待请求消息。请求消息将指示线程对API执行某些操作。一旦线程完成处理请求,它就构造一个响应消息。响应消息将包含返回的数据。如果使用BlockingCollection对请求和响应消息进行排队,则该模式非常简单。

public class SingleThreadedApiAbstraction
{
  private BlockingCollection<Request> requests = new BlockingCollection<Request>();
  private BlockingCollection<Response> responses = new BlockingCollection<Response>();

  public SingleThreadedApiAbstraction()
  {
    var thread = new Thread(Run);
    thread.IsBackground = true;
    thread.Start();
  }

  public /* Return Type */ SomeApiMethod(/* Parameters */)
  {
    var request = new Request(/* Parameters */);
    requests.Add(request); // Submit the request.
    var response = responses.Take(); // Wait for the response.
    return response.ReturnValue;
  }

  private void Run()
  {
    while (true)
    {
      var request = requests.Take(); // Wait for a request.
      // Forward the request parameters to the API.
      // Then construct a response object with the return value.
      var response = new Response(/* Returned Data */);
      responses.Add(response); // Publish the response.
    }
  }
}

这个想法是只能通过这个专用线程访问API。调用SomeApiMethod的方式和对象无关紧要。值得注意的是,如果队列为空,Take会阻塞。 Take方法是神奇发生的地方。