是否有任何现有管道在BackgroundWorker中批量运行WCF调用?
显然,因为所有Silverlight WCF调用都是异步的 - 如果我在后台工作中运行它们,它们都将立即返回。
如果这是一种运行服务调用并收集结果的好方法,我只是不想实施讨厌的黑客攻击。
编辑:我也注意到(当使用Fiddler时)任何时候都不能发送大约7个电话。即使在浏览器外运行时,此限制也适用。这是由于我的默认浏览器设置 - 还是可配置的。显然它是一个穷人的解决方案(并不适合我想要的)但我可能需要考虑的事情,以确保我的应用程序的其余部分保持响应,如果我将此作为后台任务运行而不是希望它耗尽我所有的关系。
答案 0 :(得分:9)
我认为最好的办法是让主线程将服务请求项放入与BackgroundWorker线程共享的队列中。然后,BackgroundWorker可以从队列中读取,当它检测到新项目时,启动异步WCF服务请求,并设置为处理AsyncCompletion事件。在从不同的线程调用Enqueue()或Dequeue()之前,不要忘记锁定队列。
以下是一些建议解决方案开始的代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace MyApplication
{
public class RequestItem
{
public string RequestItemData { get; set; }
}
public class ServiceHelper
{
private BackgroundWorker _Worker = new BackgroundWorker();
private Queue<RequestItem> _Queue = new Queue<RequestItem>();
private List<RequestItem> _ActiveRequests = new List<RequestItem>();
private const int _MaxRequests = 3;
public ServiceHelper()
{
_Worker.DoWork += DoWork;
_Worker.RunWorkerAsync();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
while (!_Worker.CancellationPending)
{
// TBD: Add a N millisecond timer here
// so we are not constantly checking the Queue
// Don't bother checking the queue
// if we already have MaxRequests in process
int _NumRequests = 0;
lock (_ActiveRequests)
{
_NumRequests = _ActiveRequests.Count;
}
if (_NumRequests >= _MaxRequests)
continue;
// Check the queue for new request items
RequestItem item = null;
lock (_Queue)
{
RequestItem item = _Queue.Dequeue();
}
if (item == null)
continue;
// We found a new request item!
lock (_ActiveRequests)
{
_ActiveRequests.Add(item);
}
// TBD: Initiate an async service request,
// something like the following:
try
{
MyServiceRequestClient proxy = new MyServiceRequestClient();
proxy.RequestCompleted += OnRequestCompleted;
proxy.RequestAsync(item);
}
catch (Exception ex)
{
}
}
}
private void OnRequestCompleted(object sender, RequestCompletedEventArgs e)
{
try
{
if (e.Error != null || e.Cancelled)
return;
RequestItem item = e.Result;
lock (_ActiveRequests)
{
_ActiveRequests.Remove(item);
}
}
catch (Exception ex)
{
}
}
public void AddRequest(RequestItem item)
{
lock (_Queue)
{
_Queue.Enqueue(item);
}
}
}
}
如果我能提供更多帮助,请告诉我。