Ah.
When I wrote AsyncTaskCodeActivity<T>
, I assumed that the AsyncCodeActivityContext
was in fact going to be the same instance at the beginning and end of the asynchronous method, and be available all the way through. This is not the case (which is a bit odd - not sure why the WF team made that decision).
Instead, the AsyncCodeActivityContext
can only be accessed at the beginning and end of the activity. Awkward, indeed.
The updated code below will allow you to access the context at the beginning (e.g., reading In variables) and then access the context again at the end. I also introduce an optional TState
, which can be used for storing activity state (which the activity can access throughout its execution). Let me know if this fits your needs; I haven't tested it.
public abstract class AsyncTaskCodeActivity<T, TState> : AsyncCodeActivity<T>
{
protected sealed override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
TState activityState = PreExecute(context);
context.UserState = activityState;
var task = ExecuteAsync(activityState);
return AsyncFactory<T>.ToBegin(task, callback, state);
}
protected sealed override T EndExecute(AsyncCodeActivityContext context, IAsyncResult asyncResult)
{
var result = AsyncFactory<T>.ToEnd(asyncResult);
return PostExecute(context, (TState)context.UserState, result);
}
protected virtual TState PreExecute(AsyncCodeActivityContext context)
{
return default(TState);
}
protected abstract Task<T> ExecuteAsync(TState activityState);
protected virtual T PostExecute(AsyncCodeActivityContext context, TState activityState, T result)
{
return result;
}
}
public abstract class AsyncTaskCodeActivity<T> : AsyncTaskCodeActivity<T, object>
{
}