How to Wait for Canceled Task to Finish?

前端 未结 2 2094
孤街浪徒
孤街浪徒 2020-12-18 18:24

I obviously don\'t know what I\'m doing when it comes to parallel programming with .NET 4.0. I have a simple Windows app that starts a task to do some mindless work (outputt

2条回答
  •  梦毁少年i
    2020-12-18 19:01

    Sorry, not enough reputation to just add a question as a comment to that answer. I wanted to ask how a work-around is considered an answer.

    Doesn't the code in the answer rely on some sort of user interface tweak to keep the user from starting more than one background process at a time? That's always a problem, of course.

    Here, I present an alternative that answer the question that is stated. It shows how to wait for the cancellation request to finish. It does this in a way that still lets the UI screw things up if it is not managed well, but has code that actually waits after the cancellation, if that is what is really needed. This is an excerpt from a larger C# class:

    AutoResetEvent m_TaskFinishedEvent = new AutoResetEvent( false );
    private IAsyncAction m_Operation = null;
    
    private Task WaitOnEventAsync( EventWaitHandle WaitForEvent )
    {
        return Task.Run( () => { WaitForEvent.WaitOne(); } );
    }
    
    public async void Start()
    {
    if( m_Operation != null )
        {
            // Cancel existing task
            m_Operation.Cancel();
            // Wait for it to finish. This returns control to the UI.
            await WaitOnEventAsync( m_TaskFinishedEvent );
        }
        // Start the background task.
        m_Operation = ThreadPool.RunAsync( WorkerMethod );
    }
    
    private void WorkerMethod( IAsyncAction operation )
    {
        while( m_Operation.Status != AsyncStatus.Canceled )
            ; // Add real work here.
    
        m_TaskFinishedEvent.Set();
    }
    

    This code relies on an event object to signal that the task is mostly finished. The WorkerMethod() code has not returned yet, but all useful work is done when the event is signaled.

    I did not provide a Stop() function because of how I use this code. The code to do the wait would just go in that Stop() function if that was how the code needs to work.

    Yes, you cannot use a regular Wait() function because of the cancellation exception. But the accepted answer is more of a work-around, no offense (and maybe I'm wrong?).

提交回复
热议问题