我需要在IIS中托管的wcf服务内部进行多次异步调用(可能是相关的,我不知道)。这些调用是针对其他服务的,但我通过将字符串POST到服务URL来创建它们。同步调用它们有效,但我有十几个调用,它们完全独立,所以我想通过异步调用它们来加速它们。
现在,我意识到我可以简单地使用多个线程 - 这可能是最简单的解决方案 - 但我认为我会尝试异步。
我的代码与此类似:
public delegate void Callback(string response);
public static void InvokeAsync(string request, string url, Callback callback)
where TResponse: class
{
var web = new WebClient();
web.Headers.Add("Content-Type", "application/x-www-form-urlencoded");
web.UploadStringCompleted += (sender, e) => callback.Invoke(e.Result);
web.UploadStringAsync(new Uri(url), request);
}
//...
var lockObj = new object();
foreach (var item in list)
InvokeAsync(item, url, response => { lock(lockObj) newList.Add(response); });
我认为上述应该有效;但是,我的问题是我不知道如何等待所有的回复。如果我使用计数器并在循环中等待它变为零,则不会有任何CPU来处理回调。与使用某种形式的信号量相同,我相信。是否有一种无阻塞的方式等待我收回所有回复? (更改方法签名以进行回调只会将问题提升一级,我担心。)
[编辑]这是一个非常接近的问题 - How to invoke async operation as sync? - 但我需要等待多个异步操作。
答案 0 :(得分:3)
您使用AutoResetEvent
进行此操作。
在最后两行尝试以下内容:
var waitEvent = new AutoResetEvent(false);
foreach (var item in list)
InvokeAsync(item, url, response => { lock(lockObj) newList.Add(response); waitEvent.Set(); });
while (newList.Count < list.Count)
waitEvent.WaitOne();
当newList
包含与list
一样多的项目时,应填写所有项目。当新项目进入时,您将其添加到newList
。然后,您发信号通知waitEvent
newList
发生了“{1}}。
在主线程中,您只需等到newList
中有足够的项目,然后等待newList
的更改等待,waitEvent
通知您。
答案 1 :(得分:0)
根据HTTP协议,客户端只能打开2个服务连接。