2014-09-26 41 views
4

AsyncTaskCodeActivity在執行第一個await後訪問上下文參數時失敗。例如:AsyncTaskCodeActivity和等待後丟失的上下文

public class TestAsyncTaskCodeActivity : AsyncTaskCodeActivity<int> 
{ 
    protected async override Task<int> ExecuteAsync(AsyncCodeActivityContext context, CancellationToken cancellationToken) 
    { 
     await Task.Delay(50); 
     // context has already been disposed and the next line throws 
     // ObjectDisposedException with the message: 
     // An ActivityContext can only be accessed within the scope of the function it was passed into. 
     context.Track(new CustomTrackingRecord("test")); 
     // more awaits can happen here 
     return 3; 
    } 
} 

是否有任何簡單的方法來保存上下文,以便在等待某些內容後也可以使用它?

回答

6

啊。

當我寫AsyncTaskCodeActivity<T>時,我認爲AsyncCodeActivityContext事實上將在異步方法的開始和結束時是相同的實例,並且一直可用。情況並非如此(這有點奇怪 - 不知道爲什麼WF團隊做出了這個決定)。

相反,AsyncCodeActivityContext可以可以在活動的開始和結束訪問。的確很尷尬。

下面更新後的代碼將允許您在開始時訪問上下文(例如,讀取In變量),然後在最後再次訪問上下文。我還介紹了一個可選的TState,它可以用於存儲活動狀態(活動可以在其執行過程中訪問)。讓我知道這是否符合您的需求;我沒有測試過它。

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> 
{ 
} 
+0

謝謝。我有一個類似的想法,但無法創建良好的實施。但是這個解決方案仍然有嚴重的侷限我想過使用[AsyncNativeActivity](http://blogs.msdn.com/b/tilovell/archive/2011/06/09/wf4-they-have-asynccodeactivity-why-not-asyncnativeactivity.aspx)和一個自定義調度程序以便始終訪問上下文。你怎麼看? – arturek 2014-10-13 06:17:33

+1

有什麼限制? – 2014-10-17 18:34:42

+0

自從你發佈了這個版本已經過去了一年,但我在玩同樣的問題。任何想法如何在這個遊戲中正確處理ExecutionContext? – wasabi 2015-12-21 02:28:10