【问题标题】:Threading calls to web service in a web service - (.net 2.0)在 Web 服务中线程调用 Web 服务 - (.net 2.0)
【发布时间】: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


【解决方案1】:

你的方法效率很低,很可能弊大于利。在两个调用都完成之前,您将占用一个工作线程,并且您将无缘无故地产生许多完整的线程。

考虑使您的服务异步,并使用 Web 引用的 Begin/End* 方法。

【讨论】:

  • 感谢您的诚实。不幸的是,我们无法就地修改服务,我可以,但这超出了我们的更改范围,并且会给回归带来混乱。那么在这条路线上,人们会使用 [ServiceName]Async 方法并在回调中捕获响应,然后等待其他消息完成后再继续处理? (我一直避免在 Web 服务中使用线程,所以我正在寻找一个安全的选择)。
  • 这里是 old way 来执行异步 ASMX Web 方法。这是newer way
  • 我相信您的建议,这就是我一直想去的地方。感谢您的链接,新方法是我现在正在制作的原型。再次感谢
  • 如果它适合你,请发布一个答案,展示你的新代码如何工作的框架,我会支持它。
  • 谢谢约翰 - 让我走上正轨。回到 .net 2.0 总是很有趣。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-29
  • 1970-01-01
  • 1970-01-01
  • 2014-08-23
  • 2013-07-03
相关资源
最近更新 更多