views:

83

answers:

1

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 used 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.

+1  A: 

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();
Nagg
most excellent, and terse!
Rob