Предотвращение нескольких асинхронных операций - PullRequest
1 голос
/ 10 сентября 2011

Я работаю над некоторым кодом, в котором таймер тикает каждые секунды и получаю данные из Webservice и показывает в WInform,

Что является лучшим подходом к не выполнить несколько операций одновременно?

операция должна выполняться, если предыдущая операция завершена и не выполняется.

код

  public void loadbalance()
    {
       try { //Get Data from Internet }
       catch { }
    }

    delegate void loadbalancedelegate();

    public void loadBalanceAsync()
    {
        loadbalancedelegate worker = new loadbalancedelegate(loadbalance);
        AsyncCallback LoadbalnceCallBack = new AsyncCallback(loadbalanceCompleted);

        AsyncOperation async = AsyncOperationManager.CreateOperation(null);
        worker.BeginInvoke(LoadbalnceCallBack,async);
    }

    public void loadbalanceCompleted(IAsyncResult result)
    {
         loadbalancedelegate worker = (loadbalancedelegate)          ((AsyncResult)result).AsyncDelegate;
        AsyncOperation async = (AsyncOperation)result.AsyncState;

        worker.EndInvoke(result);
    }

    delegate void setControlsBalanceDelegate(BalanceOB ball);

    void setControlsBalance(BalanceOB ball)
    {
        if (this.InvokeRequired)
            this.Invoke(new setControlsBalanceDelegate(this.setControlsBalance), new
            object[] { ball });
        else
        {    //Update Data on Form (Windows App)

        }
    }

Ответы [ 5 ]

2 голосов
/ 10 сентября 2011

Просто используйте однократный таймер. Если вы используете System.Timers.Timer, тогда установите для его свойства AutoReset значение false и используйте Start () в конце обработчика события Elapsed, чтобы перезапустить его, обычно в блоке finally. Если вы используете System.Threading.Timer, то создайте его с period of 0. Вызовите его метод Change () в обратном вызове, чтобы перезарядить его.

Особенно в случае System.Timers.Timer, очень важно, чтобы вы делали это таким образом. Не существует верхней границы для числа потоков пула потоков, которые он начнет вызывать для обработчика событий Elapsed. Если машина загружена, запуск может фактически занять некоторое время. С большим количеством возможностей для более чем одного, чтобы начать работать одновременно. И затрудняет остановку таймера.

1 голос
/ 10 сентября 2011

Вы можете просто отключить таймер до завершения одной операции или установить какое-либо поле по завершении (возможно, лучше ManualResetEventSlim из-за многопоточности).

Или взглянуть на реактивные расширения - есть много хорошихпримеры для таких вещей.

Вы можете найти много примеров здесь: 101 Образцы LINQ и очень хорошие вступления здесь: Руководство для начинающих по реактивным расширениям .И, наконец, у Somasegar есть одно сообщение в блоге, которое очень похоже на вашу проблему с Rx: Реактивные расширения для .NET (вызов веб-службы bingtranslate со всем, что вам когда-либо понадобится;))

0 голосов
/ 10 сентября 2011

Другой подход - вообще не использовать таймер.Создайте поток с циклом, который ожидает события с интервалом в одну секунду.По истечении времени ожидания позвоните в веб-службу.Затем позвоните делегату, чтобы обновить форму.Если вы хотите закрыть приложение, установите событие.Когда поток видит, что событие было установлено, он может выйти из цикла и завершиться.

0 голосов
/ 10 сентября 2011

Полагаю, вам нужно что-то вроде очереди операций.Вам нужен один отдельный поток, который проверит, содержит ли эта очередь задачи, и первая задача в очереди не выполняется.Затем, если задача доступна, вы запустите эту задачу.
Другой способ - проверить, содержит ли очередь запущенные задачи после добавления новой задачи.Если нет запущенной задачи, то вы запускаете первую задачу в отдельном потоке.Затем после завершения задачи вам необходимо проверить, содержит ли очередь другую задачу, и запустить следующую задачу.

0 голосов
/ 10 сентября 2011

Рассмотрите возможность использования Task.Wait () в пространстве имен System.Threading.Tasks.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...