我認爲你最好的選擇是讓你的主線程把服務請求項放到一個與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