【问题标题】:Multiple HTTP post requests to a web service from XML files从 XML 文件到 Web 服务的多个 HTTP 发布请求
【发布时间】:2015-08-24 03:37:34
【问题描述】:

我想在 C# 中向 Web 服务发送多个 HTTP 发布请求。例如,如果 n=3,则应发出来自 3 个 xml 文件的 HTTP 发布请求。那么我该如何实现呢?我只需要想法。我认为可以创建 n 个线程,每个线程将执行一个 http post 请求。如果可能的话,也可以在代码方面提供一些帮助。谢谢。

【问题讨论】:

    标签: c# multithreading soap xmlhttprequest


    【解决方案1】:

    此代码有效。 说明:

    • 首先,用户提供 .xml 文件的源路径和目标路径。
    • Directory.getFiles() 帮助我们获取字符串数组中的 .xml 文件。 (我们必须将 .xml 作为参数传递)。

    • 所以现在基本上发生的是对于我们在源 pat 处获得的每个文件,都会创建一个线程。

    • 但是假设用户想一次发送“n”个请求,那么一次会创建 n 个线程。
    • 除非前面的线程完成执行,否则不会创建下一组线程。
    • thread.Join() 确保了这一点。
    • 在向 Web 服务发出请求后,我们通过 getResponse() 获得响应,并且响应写入存储在目标路径的 .xml 文件中。

       using System;
       using System.Collections.Generic;
       using System.Linq;
       using System.Text;
       using System.IO;
       using System.Threading;
       using System.Xml;
       using System.Net;
       namespace ConsoleApplication4
       {
           class Program
           {
            int flag = 1;
            string destination;
            string source;
            static void Main(string[] args)
          {
          Console.ForegroundColor = ConsoleColor.Red;
      
          Console.WriteLine("**************************** Send HTTP Post Requests **************************");
          int n = 0;
          Program p = new Program();
          Console.WriteLine("Enter the number of requests you want to send at a time");
          string s = Console.ReadLine();
          int.TryParse(s, out n);
          Console.WriteLine("Enter Source");
          p.source = Console.ReadLine();
          Console.WriteLine("Enter Destination");
          p.destination = Console.ReadLine();
      
          string[] files = null;
          files = Directory.GetFiles(p.source, "*.xml", SearchOption.TopDirectoryOnly);
      
          Thread[] thread = new Thread[files.Length];
      
          int len = files.Length;
          for (int i = 0; i<len; i+=n)
          {
              int x = i;
              //Thread.Sleep(5000);
              for (int j = 0; j < n && x < len; j++)
              {
      
                  var localx = x;
                  thread[x] = new Thread(() => function(files[localx], p));
                  thread[x].Start();
                  Thread.Sleep(50);
                  //thread[x].Join();
                  x++;
              }
              int y = x - n;
              for (; y < x; y++)
              {
                  int t = y;
                  thread[t].Join();
      
              }
      
          }
      
          // thread[0] = new Thread(() => function(files[0]));
          //thread[0].Start();
          Console.ReadKey();
      
      }
      public static void function(string temp,Program p)
      {
      
          XmlDocument doc = new XmlDocument();
          doc.Load(temp);
      
          string final_d=p.destination + "response " + p.flag + ".xml";
          p.flag++;
          HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://10.76.22.135/wpaADws/ADService.asmx");
          request.ContentType = "text/xml;charset=\"utf-8\"";
          request.Accept = "text/xml";
          request.Method = "POST";
          Stream stream = request.GetRequestStream();
          doc.Save(stream);
          stream.Close();
      
          HttpWebResponse response = (HttpWebResponse)request.GetResponse();
          using (StreamReader rd = new StreamReader(response.GetResponseStream()))
          {
              string soapResult = rd.ReadToEnd();
              doc.LoadXml(soapResult);
              File.WriteAllText(final_d, doc.DocumentElement.InnerText);
      
              //XmlTextWriter xml=new XmlTextWriter(
              Console.WriteLine(soapResult);
              //Console.ReadKey();
          }
      }
      

      } }

    【讨论】:

    • 你能解释一下你的答案吗?仅仅发布没有解释的代码并不能帮助 OP 了解您所做的事情,如果它停止工作,他们将不得不再次在这里询问。
    【解决方案2】:

    使用 java.util.concurrent.ExecutorService 正如 Java 规范所说:

    提供方法来管理终止和方法的 Executor 可以产生一个 Future 来跟踪一个或多个的进度 异步任务。

    因此,使用 ExecutorService 的实现,您可以在给定数量的线程中异步或同步运行所有任务。为此,您需要创建一个 Callable 对象列表并将其传递给 ExecutorService 对象的 invokeAll 方法。 invokeAll 方法将返回 Future 对象列表的列表(每个 Future 对象将代表每个任务,并且顺序与您在传递给 invokeAll 方法的 Callable 列表中放置的顺序相同),您可以循环汇总任务的所有结果并打印它。

    您应该阅读 Executors 类的所有可用方法,这些方法返回不同的 ExecutorService 实例,因此请选择适合您的方法。

    通过这种方式,您将能够在 M 个给定线程中运行您的 N 个任务(即您的 HTTP 请求),一旦所有线程完成,您将获得 Future 对象列表,该列表将为您提供完成信息/状态每个任务。

    请确保线程中的异常处理,因为它们不会被传播,您需要显式打印堆栈跟踪。

    try {
        List<Callable<Object>> callableList = new ArrayList<Callable<Object>>();
        callableList.add(null); /*Add instance of Callable, which would have your HTTP request code in its overridden call() method*/
        callableList.add(null); /*Add instance of Callable*/
        callableList.add(null); /*Add instance of Callable*/
    
        //Specify how many threads you want or need to operate. Read other methods of Executors which return different instances of ExecutorService
        final ExecutorService service = Executors.newFixedThreadPool(3);
    
        //This will invoke all your N tasks in specified M threads ...
        List<Future<String[]>> futureObjects = service.invokeAll(callableList);  //futureObjects will contain result of each thread execution
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    

    检查下面的伪示例:

    【讨论】:

    • 谢谢...但我需要 C# 语言。如果你能用 C# 告诉我,那将是一个很大的帮助。 :)
    • 好的,你之前没有 C# 单词和标签 :) 无论如何你有这个想法 - 在 c# 中会有一些 API 可以让你进行异步调用并编译结果。您只需要知道使用它的语法,否则每种语言的想法都是相同的。这是 C# 多线程 API 的一个很好的链接,我可以为您提供帮助 - stackoverflow.com/questions/1557538/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    • 2014-04-28
    相关资源
    最近更新 更多