开发者

Preventing Multiple Async Operations

i am working on some code where a timer tick every seconds and and get data from Webservice and Shows in on WInform ,

What is the best approach to not run Multiple operations at same time ?

operation should run if previous operation completed and not running.

the code is

  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 setC开发者_运维问答ontrolsBalanceDelegate(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)

        }
    }


Just use a one-shot timer. If you use System.Timers.Timer then set its AutoReset property to false and use Start() at the end of your Elapsed event handler to restart it, typically in a finally block. If you use System.Threading.Timer then construct it with a period of 0. Call its Change() method in the callback to recharge it.

Particularly in the case of System.Timers.Timer, it is pretty important that you do it this way. There's no upper bound on the number of threadpool threads it will start to call your Elapsed event handler. If the machine is loaded, it can take a while for them to actually start running. With plenty of opportunity for more than one to start running at the same time. And making it difficult to stop the timer.


you can just disable the timer till one operation completes or set some field on completion (maybe better a ManualResetEventSlim because of multithreading).

Or have a look at the reactive extensions - there are a lot of good examples for such things.

You can find many samples here: 101 LINQ Samples, and very good intros here: Beginner's Guide to the Reactive Extensions. And finally Somasegar has one blog-post that is very similar to your problem with Rx: Reactive Extensions for .NET (webservice call of bingtranslate with all you ever need ;) )


Consider using Task.Wait() in System.Threading.Tasks namespace.


I suppose you need something like operation queue. You need one separate thread which will check if this queue contains tasks and first task in queue is not running. Then if task available you will run this task.
Another way is to check if queue contains running tasks after adding new task. If there are no running task then you run first task in separate thread. Then after task finished you need to check if queue contains another task and to run next task.


Another approach would be not to use a timer at all. Create a thread with a loop that waits on an event with a one second timeout. When the timeout expires call the web service. Then call the delegate to update the form. When you want to close the app, set the event. When the thread sees the event was set it can exit the loop and terminate.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜