我的任务是为现有的(会话满的)服务编写WCF服务主机(服务器) - 到目前为止并不难。该服务是一个ADO代理服务器,它代理ADO与各种后端数据库的连接。这在大多数情况下运行良好,但我需要支持的一个ADO .NET数据提供程序是作为连接到非线程安全的非托管代码(C)API的驱动程序实现的。
首选解决方案,使代码线程安全或实现线程安全的托管驱动程序现在不在桌面上。有人建议我可以将多个进程作为一种后端或二级代理进行旋转,但是当我第一次听到它时,这让我感到噩梦,甚至在我试用实现时也是如此。
我的问题是,我在这里缺少另一种解决方案吗?到目前为止,我已经玩过ConncurrencyMode.Single和UseSynchronization = true,但事情的真正核心是sessionfull并且具有非线程安全的后端。到目前为止没有运气。我是否坚持代理连接到多个进程,或者其他人可以提出更优雅的解决方案吗?
谢谢!
答案 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
方法是神奇发生的地方。