如何在Silverlight BackgroundWorker中运行批处理的WCF服务调用

Sim*_*ver 2 silverlight backgroundworker

是否有任何现有的管道在BackgroundWorker中批量运行WCF调用?

显然,因为所有Silverlight WCF调用都是异步的 - 如果我在后台工作程序中运行它们,它们都将立即返回.

我只是不想实施讨厌的黑客,如果这是一个很好的方式来运行服务调用并收集结果.

  • 无论他们做了什么顺序
  • 所有操作都是独立的
  • 我想一次运行不超过5件物品

编辑:我也注意到(当使用Fiddler时)任何时候都不能发送大约7个电话.即使在浏览器外运行时,此限制也适用.这是由于我的默认浏览器设置 - 还是可配置的.显然它是一个穷人的解决方案(并不适合我想要的)但我可能需要考虑的事情,以确保我的应用程序的其余部分保持响应,如果我将此作为后台任务运行而不是希望它耗尽我所有的联系.

Jim*_*rdy 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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我能提供更多帮助,请告诉我.