我有一个页面需要将来自四个不同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;
}
答案 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