【问题标题】:How to make Multiple requests in parallel to a webservice in C#如何在 C# 中与 Web 服务并行发出多个请求
【发布时间】:2012-03-23 17:57:24
【问题描述】:

我需要调用以下 3 个 WCF 服务,

var client = new WebClient();
    client.Headers[HttpRequestHeader.ContentType] = "application/json";
    var resultJson1 = client.UploadString("http://localhost:45868/Product/GetAvailableProductsByContact",
                                         jsonser1);
var resultJson2= client.UploadString("http://localhost:45868/Product/GetMemberProductsByContact",
                                         jsonser2);

var resultJson3= client.UploadString("http://localhost:45868/Product/GetCoachProductsByContact",
                                         jsonser3);

这需要花费大量时间才能获得结果并显示在页面上。谁能帮助我如何并行执行它们?

【问题讨论】:

  • 把这个放到另一个类中多线程吧?

标签: c# wcf c#-4.0 asynchronous parallel-processing


【解决方案1】:

您可以使用task parallelism library:

Task<string>[] taskArray = new Task<string>[]
    {
        Task.Factory.StartNew(() => {
            var client = new WebClient();
            client.Headers[HttpRequestHeader.ContentType] = "application/json";
            var json = client.UploadString("http://localhost:45868/Product/GetAvailableProductsByContact",
                                     jsonser1);
            return json;
        }),
        Task.Factory.StartNew(() => {
            var client = new WebClient();
            client.Headers[HttpRequestHeader.ContentType] = "application/json";
            var json = client.UploadString("http://localhost:45868/Product/GetMemberProductsByContact",
                                     jsonser2);
            return json;
        }),
        Task.Factory.StartNew(() => {
            var client = new WebClient();
            client.Headers[HttpRequestHeader.ContentType] = "application/json";
            var json = client.UploadString("http://localhost:45868/Product/GetCoachProductsByContact",
                                     jsonser3);
            return json;
        }),
    };

// the request for .Result is blocking and waits until each task
// is completed before continuing; however, they should also all
// run in parallel instead of sequentially.
var resultJson1 = taskArray[0].Result;
var resultJson2 = taskArray[1].Result;
var resultJson3 = taskArray[2].Result;

或者,由于您的请求都非常相似,仅 url 和上传字符串不同,您可以使用 LINQ AsParallel 数组处理:

var requests = new [] {
    new { Url = "http://localhost:45868/Product/GetAvailableProductsByContact", Input = jsonser1 },
    new { Url = "http://localhost:45868/Product/GetMemberProductsByContact", Input = jsonser2 },
    new { Url = "http://localhost:45868/Product/GetCoachProductsByContact", Input = jsonser3 },
};
var result = requests.AsParallel().Select(req => {
    var client = new WebClient();
    client.Headers[HttpRequestHeader.ContentType] = "application/json";
    var json = client.UploadString(req.Url, req.Input);
    return json;
}).ToArray();

// when above code has finished running, all tasks are completed
var resultJson1 = result[0];
var resultJson2 = result[1];
var resultJson3 = result[2];

【讨论】:

  • 非常感谢您的回答。这确实会加快进程。
  • 我没有测试上面的任何代码。让我知道它是否会生成编译时或运行时错误。您可能还想熟悉AggregateException,以便在一个或多个请求无法完成时处理错误。
【解决方案2】:

您可以使用begin/end pattern:

这个例子展示了如何并行调用两个ws。您可以将这个想法扩展到 N 个服务。

【讨论】:

    【解决方案3】:

    尝试创建一个 Task 来执行您的每个调用 (MSDN)

    您可以尝试执行以下操作

    首先为您的每个呼叫创建一个Task&lt;String&gt;

    var client = new WebClient();
    client.Headers[HttpRequestHeader.ContentType] = "application/json";
    
    Task<String> task1 = Task.Factory.StartNew(() => {
        client.UploadString("http://localhost:45868/Product/GetAvailableProductsByContact",
                                             jsonser1);
    });
    

    冲洗并重复其他 2 个

    之后,您可以通过调用 task1.Valuetask2.Valuetask3.Value 来加入 3 Task&lt;String&gt; 的执行,这将返回一个 String

    【讨论】:

    • @mellamokb 打败了我!他/她的第二个答案很棒。
    • 请注意,在并行任务之间共享client 的同一实例时要小心。 WebClient 实例未声明为线程安全的,这就是为什么我在示例中明确努力为每个服务调用创建单独的 WebClient 对象实例。
    • 感谢@mellamokb 的警告
    猜你喜欢
    • 2014-10-20
    • 1970-01-01
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多