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

标签 silverlight backgroundworker

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

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

如果有运行服务调用和收集结果的好方法,我只是不想实现令人讨厌的 hack。

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

编辑:我还注意到(在使用 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);
            }
        }
    }
}

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

关于silverlight - 如何在 Silverlight BackgroundWorker 中运行批处理 WCF 服务调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2465442/

相关文章:

Silverlight:如何将 True 传递给 CommandParameter?

Silverlight 自动在 http 和 https 之间选择安全传输模式

silverlight - 从 Silverlight 应用程序检索 Sharepoint 中的当前用户登录信息

c# - 黑屏只是闪烁了一会儿

c# - 消息过滤器指示应用程序正忙,同时使用多个 web 浏览器控件

VB.Net 正确关闭在后台工作程序上运行的异步套接字服务器

c# - `RunWorkerCompleted` 并非总是被解雇

silverlight - 在静态方法中使用依赖属性回调和动画进行数据绑定(bind)

c# - 如何同时运行两个或多个sql查询?

c# - 在 WPF 中使用 BackgroundWorker 更新 UI