【发布时间】:2012-03-29 17:19:20
【问题描述】:
有一个关于在 Web 服务中进行并行 Web 服务调用的最佳做法的问题。这是一个备用计划,以防项目的另一部分无法按时交付。我宁愿有一些有用的东西,即使它被丢弃,所以最终用户不会被打断。
我们的门户将收到一条消息,将该消息拆分为 2 条消息,然后对我们的代理进行 2 次调用。这些需要在单独的线程上以降低超时。
一种解决方案是执行类似于(伪代码)的操作: *更新:没有想象的那么高效,执行速度很快,但不如通过委托异步调用。
XmlNode DNode = GetaGetDemoNodeSomehow();
XmlNode ENode = GetAGetElNodeSomehow();
XmlNode elResponse;
XmlNode demResponse;
Thread dThread = new Thread(delegate
{
//Web Service Call
GetDemographics d = new GetDemographics();
demResponse = d.HIALRequest(DNode);
});
Thread eThread = new Thread(delegate
{
//Web Service Call
GetEligibility ge = new GetEligibility();
elResponse = ge.HIALRequest(ENode);
});
dThread.Start();
eThread.Start();
dThread.Join();
eThread.Join();
//combine the resulting XML and return it.
//Maybe throw a bit of logging in to make architecture happy
我们想到的另一个选择是创建一个工作类,并将服务信息传递给它并让它执行。这将使我们能够更好地控制正在发生的事情,但可能会增加额外的开销。
提出的另一个选项是 2 个异步调用并通过标志管理返回: 更新: *这不如我尝试的更新方式有效。这比我下面的慢 25%(运行优化)。
personRevisedService.GetDemoCompleted += new GetDemoCompletedEventHandler(GetDemo_Completed);
personRevisedService.GetDemoAsync(SomeXML);
门户服务每天将被调用约 50,000 次。
我不想给这个傻瓜镀金。
我正在寻找重量轻的东西。在代理上调用的服务确实设置了超时限制,并且已经被大量记录和审计,所以我并不担心那部分。
这是 .NET 2.0 ,尽管我很想升级,但现在还不能。所以请把 > 2.0 的所有好东西都放在外面。
更新
我决定使用委托给他们打电话。因为这是一个测试,所以我两次调用同一个服务,因为另一个服务尚未构建。它的执行速度平均比使用 [WebServiceName]Async(...) 快 20-30%,
public delegate XmlElement HServiceDelegate(XmlElement xml);
HServiceDelegate del1 = new HServiceDelegate(ws1.HGetDemographics);
HServiceDelegate del2 = new HServiceDelegate(ws2.GetDemographics);
IAsyncResult async1 = del1.BeginInvoke(x1.DocumentElement, callback1, null);
IAsyncResult async2 = del2.BeginInvoke(x2.DocumentElement, callback2, null);
//Not sure if this is the most efficient
while (!async1.IsCompleted && !async2.IsCompleted)
{
System.Threading.Thread.Sleep(5);
}
void callback1(IAsyncResult result)
{
AsyncResult r = (System.Runtime.Remoting.Messaging.AsyncResult)result;
HServiceDelegate caller = (HServiceDelegate)r.AsyncDelegate;
r1 = caller.EndInvoke(result);
}
【问题讨论】:
-
顺便说一句,在 2 个 new 线程上发送两条消息并等待它们几乎没有什么好处。相反,将发送其中一个的逻辑保留在主线程上,并且只生成 1 个 new 线程来发送另一个。如果主线程无论如何都会闲置,那么将工作卸载到不同的线程是没有意义的。
标签: c# multithreading web-services .net-2.0