asp.net中异步的多个webrequests?

时间:2009-10-21 15:43:29

标签: asp.net asynchronous httpwebrequest

我有一个页面需要将来自四个不同webrequests的数据合并到一个项目列表中。目前,我按顺序运行这些,附加到单个列表,然后将该列表绑定到我的转发器。

但是,我希望能够异步调用这四个Web请求,以便它们可以同时运行并节省加载时间。不幸的是,我见过的所有异步教程和文章都处理了一个请求,使用完成的处理程序继续处理。

如何同时执行这四项(这可能会增加!),请记住每项结果都必须输入一个列表?

非常感谢!

编辑:我正在做的简化示例:

var itm1 = Serialize(GetItems(url1));
list.AddRange(itm1);
var itm2 = Serialize(GetItems(url2));
list.AddRange(itm2); 

string GetItems(string url)
{
     var webRequest = WebRequest.Create(url) as HttpWebRequest;
     var response = webRequest.GetResponse() as HttpWebResponse;

     string retval;
     using (var sr = new StreamReader(response.GetResponseStream()))
     { retval = sr.ReadToEnd(); }
     return retval;
} 

4 个答案:

答案 0 :(得分:2)

这应该非常简单,因为您的最终数据取决于所有四个请求的结果。

您可以做的是创建4个异步委托,每个委托指向适当的Web方法。对所有这些做一个BeginInvoke。然后使用WaitHandle等待所有。在您的情况下,不需要使用回调,因为您不希望在处理Web方法时继续,而是等到所有Web方法都完成执行。

只有在执行了所有Web方法之后,才会执行wait语句之后的代码。在这里你可以结合4个结果。

以下是我为您开发的示例代码:

class Program
    {
        delegate string DelegateCallWebMethod(string arg1, string arg2);

        static void Main(string[] args)
        {
            // Create a delegate list to point to the 4 web methods
            // If the web methods have different signatures you can put them in a common method and call web methods from within
            // If that is not possible you can have an List of DelegateCallWebMethod
            DelegateCallWebMethod del = new DelegateCallWebMethod(CallWebMethod);

            // Create list of IAsyncResults and WaitHandles
            List<IAsyncResult> results = new List<IAsyncResult>();
            List<WaitHandle> waitHandles = new List<WaitHandle>();

            // Call the web methods asynchronously and store the results and waithandles for future use
            for (int counter = 0; counter < 4; )
            {
                IAsyncResult result = del.BeginInvoke("Method ", (++counter).ToString(), null, null);
                results.Add(result);
                waitHandles.Add(result.AsyncWaitHandle);
            }

            // Make sure that further processing is halted until all the web methods are executed
            WaitHandle.WaitAll(waitHandles.ToArray());

            // Get the web response
            string webResponse = String.Empty;
            foreach (IAsyncResult result in results)
            {
                DelegateCallWebMethod invokedDel = (result as AsyncResult).AsyncDelegate as DelegateCallWebMethod;
                webResponse += invokedDel.EndInvoke(result);
            }
        }


        // Web method or a class method that sends web requests
        public static string CallWebMethod(string arg1, string arg2)
        {
            // Code that calls the web method and returns the result

            return arg1 + " " + arg2 + " called\n";
        }

    }

答案 1 :(得分:1)

如何在每个单独的线程上启动每个请求,然后将结果附加到列表中?

答案 2 :(得分:1)

您可以测试以下代码:

Parallel.Invoke(()=&gt;                         {
                            // TODO运行你的请求......                         });

您需要参考并行扩展: http://msdn.microsoft.com/en-us/concurrency/bb896007.aspx

答案 3 :(得分:1)

@Josh:关于发送4个(可能更多)异步请求并跟踪响应(例如以列表形式提供信息)的问题。您可以编写4个请求和4个响应处理程序,但由于您可能会有更多请求,因此可以编写异步循环。经典的for循环由init,条件和增量组成。您可以将经典的for循环分解为while循环,但仍然是等效的。然后将while循环变为递归函数。现在你可以使它异步。我在http://asynchronous.me/处放了一些示例脚本。在您的情况下,在选项中选择for循环。如果您希望按顺序发送请求,即前一个响应之后的一个请求(request1,response1,request2,response2,request3,response3等),则选择Serial communication(即顺序),但代码更多一点错综复杂。另一方面,如果您不关心接收响应的顺序(随机顺序),则选择并行通信(即并发),代码更直观。在任何一种情况下,每个响应都将通过标识符(一个简单的整数)与其相应的请求相关联,因此您可以跟踪所有响应。该网站将为您提供示例脚本。示例使用JavaScript编写,但适用于任何语言。根据您的语言和编码首选项调整脚本。使用该脚本,您的浏览器将异步发送4个请求,并且通过标识符,您将能够跟踪响应对应的请求。希望这可以帮助。 / Thibaud Lopez Schneider