开发者

Adding cancel ability and exception handling to async code

开发者 https://www.devze.com 2022-12-23 13:46 出处:网络
I have this sample code for async operations (copied from the interwebs) public class LongRunningTask {

I have this sample code for async operations (copied from the interwebs)

public class LongRunningTask
{
    public LongRunningTask()
    { 
    //do nowt
    }
    public int FetchInt()
    {
        Thread.Sleep(2000);        
        return 5;
    }
}

public delegate TOutput SomeMethod<TOutput>();
public class GoodPerformance
{
    public void BeginFetchInt()
    {
        LongRunningTask lr = new LongRunningTask();
        SomeMethod<int> method = new SomeMethod<int>(lr.FetchInt);

        // method is state object us开发者_开发技巧ed to transfer result
        //of long running operation
        method.BeginInvoke(EndFetchInt, method);

    }

    public void EndFetchInt(IAsyncResult result)
    {        
        SomeMethod<int> method = result.AsyncState as SomeMethod<int>;        
        Value = method.EndInvoke(result);

    }
    public int Value { get; set; }
}

Other async approaches I tried required the aysnc page attribute, they also seemed to cancel if other page elements where actioned on (a button clicked), this approach just seemed to work.

I’d like to add a cancel ability and exception handling for the longRunningTask class, but don’t erm, really know how.


In example:

public class ValueEventArgs : EventArgs
{
    public int Value { get;set;}
}
public class ExceptionEventArgs : EventArgs
{
    public Exception Exception { get;set;}
}
public class LongRunningTask
{
    private bool canceled = false;

    public event EventHandler<ValueEventArgs> Completed = delegate {}
    public event EventHandler<ExceptionEventArgs> GotError = delegate {}

    public void Cancel()
    {
        canceled = true;
    }

    public void FetchInt()
    {
        try
        {
            int result = 0;
            for (int i = 0; i < 1000; i++)
            {
                if (canceled)
                    return;
                result++; 
            }
            Completed(this, new ValueEventArgs {Value = result});
        }
        catch(Exception exc)
        {
            GotError(this, new ExceptionEventArgs { Exception = exc });
        }
    }

    public void BeginFetchInt()
    {
        ThreadPool.QueueUserWorkItem(i => FetchInt());
    }
}

And somewhere:

    LongRunningTask task = new LongRunningTask();
    task.Completed +=new EventHandler<ValueEventArgs>(task_Completed); 
    task.GotError +=new EventHandler<ExceptionEventArgs>(task_GorError);
    task.BeginFetchInt();
    //in any moment until it calculates you may call:
    task.Cancel();
0

精彩评论

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