11

AsyncTargetingPackを使用して、.NET4.0を対象とするMVC4コントローラーアクション内のSQLServerにいくつかの情報を非同期で記録しようとしています。.NET 4.5に直接ジャンプしますが、私のアプリはAzureにあり、更新を待っています...

このコードは期待どおりに機能します(例外がスローされることなく行がデータベースに書き込まれます):

public class SystemActionLogger : ISystemActionLogger
{
    private readonly ActionBlock<Tuple<SystemAction, object>> actionBlock;

    public SystemActionLogger(ISystemActionLogEntryRepository repository)
    {
        actionBlock = new ActionBlock<Tuple<SystemAction, object>>(
            entry => TaskEx.Run(async () =>
                {
                    string data = await JsonConvert.SerializeObjectAsync(entry.Item2);
                    await repository.PersistAsync(new SystemActionLogEntry(entry.Item1, data));
                }));
    }

    public void Log(SystemAction systemAction, object data)
    {
        actionBlock.Post(new Tuple<SystemAction, object>(systemAction, data));
    }
}

そして、このコードはNullReferenceExceptionをスローします。

public class SystemActionLogger : ISystemActionLogger
{
    private readonly ActionBlock<Tuple<SystemAction, object>> actionBlock;

    public SystemActionLogger(ISystemActionLogEntryRepository repository)
    {
        actionBlock = new ActionBlock<Tuple<SystemAction, object>>(async entry =>
            {
                string data = await JsonConvert.SerializeObjectAsync(entry.Item2);
                await repository.PersistAsync(new SystemActionLogEntry(entry.Item1, data));
            });
    }

    public void Log(SystemAction systemAction, object data)
    {
        actionBlock.Post(new Tuple<SystemAction, object>(systemAction, data));
    }
}

NullReferenceException:"オブジェクト参照がオブジェクトのインスタンスに設定されていません。"

Server stack trace: 
   at System.Web.ThreadContext.AssociateWithCurrentThread(Boolean setImpersonationContext)
   at System.Web.HttpApplication.OnThreadEnterPrivate(Boolean setImpersonationContext)
   at System.Web.LegacyAspNetSynchronizationContext.CallCallbackPossiblyUnderLock(SendOrPostCallback callback, Object state)
   at System.Web.LegacyAspNetSynchronizationContext.CallCallback(SendOrPostCallback callback, Object state)
   at System.Runtime.CompilerServices.TaskAwaiter.<>c__DisplayClassa.<OnCompletedInternal>b__0(Task param0)

Exception rethrown at [0]: 
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<ThrowAsync>b__1(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

すべて外部コードであるため、例外を確認することはできません。コードの2番目のブロックが失敗する理由がわかりません。これは私が最初に書いたコードです。

私は何が間違っているのですか?

4

3 に答える 3

0

データフローは.NET4.5でのみ機能します。.NET 4.0で実行しているという事実はサポートされておらず、誤った例外が発生している可能性があります。

于 2012-12-31T17:32:08.873 に答える
-2

Web サービスが別の WCF サービスを非同期で呼び出していたときに、.net4.5 でこの問題が発生しました。Wait()応答 (テレメトリ イベント) を気にしなかったので、単純に短い時間を追加しました。

public static void Event(string key, string message) {
    Telemetry.Event(key, message).Wait(100);
}
于 2014-06-06T23:37:33.027 に答える