繁体   English   中英

防止多个异步操作

[英]Preventing Multiple Async Operations

我正在编写一些代码,其中计时器每秒钟滴答一次 ,并从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)

        }
    }

只需使用一个计时器。 如果使用System.Timers.Timer,则将其AutoReset属性设置为false,并在Elapsed事件处理程序的末尾使用Start()来重新启动它,通常是在finally块中。 如果使用System.Threading.Timer,则以0 周期构造它。在回调中调用其Change()方法为它充电。

特别是在System.Timers.Timer的情况下,以这种方式执行非常重要。 它将开始调用Elapsed事件处理程序的线程池线程数没有上限。 如果计算机已加载,则它们可能需要一段时间才能真正开始运行。 有很多机会可以同时开始多个。 而且很难停止计时器。

您可以只禁用计时器,直到一个操作完成或在完成时设置某些字段为止(由于多线程,最好使用ManualResetEventSlim)。

或查看反应式扩展-有很多很好的例子。

您可以在这里找到许多示例: 101个LINQ示例 ,以及以下非常好的介绍: 《 Reactive Extensions入门指南》 最后,Somasegar的博客文章与Rx的问题非常相似: .NET的Reactive Extensions (使用bingtranslate的webservice调用可满足您的所有需求;))

考虑在System.Threading.Tasks命名空间中使用Task.Wait()

我想您需要像操作队列这样的东西。 您需要一个单独的线程,该线程将检查此队列中是否包含任务,并且队列中的第一个任务未运行。 然后,如果任务可用,您将运行此任务。
另一种方法是在添加新任务后检查队列是否包含正在运行的任务。 如果没有正在运行的任务,那么您将在单独的线程中运行第一个任务。 然后,任务完成后,您需要检查队列是否包含另一个任务并运行下一个任务。

另一种方法是根本不使用计时器。 创建一个带有循环的线程,该线程等待事件超时一秒。 超时到期后,请调用Web服务。 然后呼叫代表以更新表格。 当您要关闭应用程序时,请设置事件。 当线程看到事件已设置时,它可以退出循环并终止。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM