如何在 Silverlight BackgroundWorker 中运行批量 WCF 服务调用

2024-03-30

是否有任何现有的管道可以在 a 中批量运行 WCF 调用后台工作者 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(VS.95).aspx?

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

如果有一种很好的方法来运行服务调用并收集结果,我只是不想实施令人讨厌的黑客攻击。

  • 它们以什么顺序完成并不重要
  • 所有操作都是独立的
  • 我希望同时运行的项目不超过 5 个

Edit:我还注意到(使用 Fiddler 时)每次最多只能发送 7 个呼叫。即使在浏览器外运行时,此限制也适用。这是由于我的默认浏览器设置造成的 - 或者也可以配置。显然,这是一个穷人的解决方案(并且不适合我想要的),但如果我将其作为后台任务运行并且不这样做,我可能需要考虑一些事情,以确保我的应用程序的其余部分保持响应希望它用完我所有的连接。


我认为最好的选择是让主线程将服务请求项放入与 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);
            }
        }
    }
}

如果我可以提供更多帮助,请告诉我。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Silverlight BackgroundWorker 中运行批量 WCF 服务调用 的相关文章

随机推荐