Как выполнить пакетные вызовы службы WCF в Silverlight BackgroundWorker - PullRequest
2 голосов
/ 17 марта 2010

Существует ли какой-либо способ подключения для выполнения вызовов WCF в пакетном режиме в BackgroundWorker ?

Очевидно, что все вызовы Silverlight WCF являются асинхронными - если я выполню их все в фоновом режиме, они все сразу же вернутся.

Я просто не хочу реализовывать неприятный хак, если есть хороший способ запуска сервисных вызовов и сбора результатов.

  • Не имеет значения, в каком порядке они выполняются в
  • Все операции являются независимыми
  • Я бы хотел, чтобы одновременно работало не более 5 элементов

Редактировать : я также заметил (при использовании Fiddler), что одновременно можно отправлять не более 7 звонков. Это ограничение действует даже при работе вне браузера. Это из-за моих настроек браузера по умолчанию - или настраивается тоже. очевидно, это решение для бедного человека (и не подходящее для того, что я хочу), но кое-что, что я, вероятно, должен принять во внимание, чтобы убедиться, что остальная часть моего приложения остается отзывчивой, если я запускаю это как фоновую задачу хочу, чтобы это использовало все мои связи.

1 Ответ

9 голосов
/ 22 марта 2010

Я думаю, что лучше всего было бы, чтобы ваш основной поток помещал элементы запроса на обслуживание в очередь, которая используется совместно с потоком 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);
            }
        }
    }
}

Дайте мне знать, если я смогу предложить дополнительную помощь.

...