如何在Silverlight BackgroundWorker中运行批处理的WCF服务调用 [英] How to run batched WCF service calls in Silverlight BackgroundWorker

查看:72
本文介绍了如何在Silverlight BackgroundWorker中运行批处理的WCF服务调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

BackgroundWorker ?

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

Obviously since all Silverlight WCF calls are async - if I run them all in a backgroundworker they will all return instantly.

如果有一种不错的方式来运行服务调用并收集结果,我只是不想实施讨厌的破解程序.

I just don't want to implement a nasty hack if theres a nice way to run service calls and collect the results.

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

编辑:我还注意到(使用Fiddler时)一次最多只能发送大约7个电话.即使在浏览器不足的情况下,此限制也适用.这是由于我的默认浏览器设置-还是可配置的.显然,这是一个可怜的人的解决方案(并且不适合我想要的),但是如果我将其作为后台任务运行并且不执行此操作,则可能需要考虑确保我的应用程序其余部分保持响应能力希望它用完我所有的连接.

Edit: i've also noticed (when using Fiddler) that no more than about 7 calls are able to be sent at any one time. Even when running out-of-browser this limit applies. Is this due to my default browser settings - or configurable also. obviously its a poor man's solution (and not suitable for what i want) but something I'll probably need to take account of to make sure the rest of my app remains responsive if i'm running this as a background task and don't want it using up all my connections.

推荐答案

我认为最好的选择是让主线程将服务请求项放入与BackgroundWorker线程共享的Queue中.然后,BackgroundWorker可以从队列中读取,并在检测到新项目时启动异步WCF服务请求,并进行设置以处理AsyncCompletion事件.在从其他线程调用Enqueue()或Dequeue()之前,请不要忘记锁定队列.

I think your best bet would be to have your main thread put service request items into a Queue that is shared with a BackgroundWorker thread. The BackgroundWorker can then read from the Queue, and when it detects a new item, initiate the async WCF service request, and setup to handle the AsyncCompletion event. Don't forget to lock the Queue before you call Enqueue() or Dequeue() from different threads.

以下是一些建议开始解决方案的代码:

Here is some code that suggests the beginning of a solution:

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);
            }
        }
    }
}

让我知道是否可以提供更多帮助.

Let me know if I can offer more help.

这篇关于如何在Silverlight BackgroundWorker中运行批处理的WCF服务调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆