我认为你最好的选择是让你的主线程把服务请求项放到一个与BackgroundWorker线程共享的队列中。然后,BackgroundWorker可以从Queue中读取数据,并在它检测到新项目时,启动异步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);
}
}
}
}
让我知道如果我可以提供更多的帮助。
谢谢吉姆 - 除了你没有解决的最重要的事情是,我不希望所有的请求一次运行。我认为毫秒计时器应该检查ActiveRequests> = 3。我喜欢排队的想法。其中一个通用类我总是忘记 – 2010-03-22 17:27:15
Simon, 您不必一次运行所有请求。我建议的计时器只是为了避免持续检查队列。 我通过检查_MaxRequests,并通过包括一个示例调用异步服务,与相应的Completed事件处理程序更新我的答案代码。希望这会让你更接近一点。 – 2010-03-22 20:08:23