[英]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.