代码之家  ›  专栏  ›  技术社区  ›  gregmac

对多个服务器的并行WCF调用

  •  0
  • gregmac  · 技术社区  · 14 年前

    我有一个WCF服务(同一个)在多个服务器上运行,我想从一个客户机并行调用所有实例。我使用ChannelFactory和接口(契约)来调用服务。每个服务都有一个本地 <endpoint> 在.config文件中定义的客户端。

    我要做的是构建某种通用框架来避免代码重复。

    例如,单个线程中的同步调用如下所示:

        Dim remoteName As String = "endpointName1"
        Dim svcProxy As ChannelFactory(Of IMyService) = New ChannelFactory(Of IMyService)(remoteName)
        Try
            svcProxy.Open()
            Dim svc As IMyService = svcProxy.CreateChannel()
            nodeResult = svc.TestRemote("foo")
        Finally
            svcProxy.Close()
        End Try
    

    我遇到的困难是如何指定并实际调用实际的远程方法(例如“TestRemote”),而不必为每个方法复制上面的代码,以及调用该方法的所有与线程相关的内容。

    Dim results as Dictionary(Of Node, ExpectedReturnType) 
    results = ParallelInvoke(IMyService.SomeMethod, parameter1, parameter2) 
    

    其中ParallelInvoke()将方法作为参数,以及参数(paramArray或object()。。然后在每个远程节点上运行请求,阻塞直到它们都返回答案或超时,然后将结果返回到字典中,其中键作为节点,值作为它返回的值。

    然后,我可以(根据方法)挑选出所需的单个值,或者将每个服务器的所有值聚合在一起,等等。

    谢谢

    2 回复  |  直到 14 年前
        1
  •  3
  •   Pawel Pabich    14 年前
     public static TResult MakeCall<TService, TResult>(Func<TService, TResult> method,  string remoteName)
            {
                // try not to create the factory object for each call, it can be a singleton
                var factory = GetFactory<TService>(remoteName);
                TService proxy = default(TService);
                TResult result = default(TResult);
                try
                {
                    proxy = factory.CreateChannel();
                    result = method(proxy);
                }
                finally
                {
                    // proxy disposal is a bit tricky in WCF and you might need to read more about Close/Abort
                     Close(proxy);                    
    
                }
                return result;
            }
    

    它允许您在任何接口上调用任何方法,而不必复制管道代码。

    public interface IMyService
            {
                int Sum(int a, int b);
                int Max(int a, int b);
            }
    

    公共接口IMyService2 { 布尔检验(字符串值);

       static void Main(string[] args)
            {
                var a = 12;
                var b = 12;
                var r1 = MakeCall((IMyService proxy) => proxy.Sum(a, b),  "endpoint1");
                var a1 = 12;
                var b1 = 14;
                var r2 = MakeCall((IMyService proxy) => proxy.Max(a1, b1), "endpoint1");
                var r3 = MakeCall((IMyService2 proxy) => proxy.Test("test"), "endpoint2");
            }
    

    您可以使用MakeCall作为最终解决方案的构建块。

        2
  •  1
  •   Chris O    14 年前

    一种方法是使用:

    System.Threading.ThreadPool.QueueUserWorkItem(…)

    请在此处查找VB语法: http://msdn.microsoft.com/en-us/library/4yd16hza.aspx