Async logging eine NullReferenceException auslösen

Ich versuche, asynchron Protokoll einige Informationen zu SQL-Server innerhalb einer MVC-4-controller-action-Ausrichtung .NET 4.0 mit AsyncTargetingPack. Ich würde springen Sie direkt zu .NET 4.5, aber mein app lebt in Azure und wir warten immer noch auf das update...

Dieser code wie erwartet funktioniert (eine Zeile geschrieben zu meiner Datenbank keine Ausnahmen):

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));
    }
}

Und dieser code wirft eine NullReferenceException-Ausnahme:

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: "Objektverweis nicht auf eine Instanz eines Objekts."

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()

Ich habe keinen Einblick in die Ausnahme, da es alle externen code. Ich verstehe nicht, warum der zweite code-block, der fehlschlägt. Dies ist der code, den ich ursprünglich schrieb.

Was mache ich falsch?

  • ASP.NET braucht spezielle Unterstützung für async, die Hinzugefügt wurde .NET 4.5. Ich würde nicht versuchen, mit dem Async Targeting Pack auf ASP.NET apps für .NET 4.0 - ein paar einfache Dinge, die funktionieren würde, aber die ASP.NET pipeline ist einfach nicht bereit zu sehen async code.
  • Ihr stack trace enthält einen Verweis auf LegacyAspNetSynchronizationContext ein Typ Hinzugefügt .NET 4.5. Wussten Sie installieren .NET 4.5 auf Ihrem Azure-server?
  • Hey Stephen, vielen Dank für die Antwort. Ich hatte gesehen, eine ähnliche Antwort von dir auf andere SO posten und hatte gehofft, dass dies nicht der Fall war, vor allem, da der erste block von code funktioniert. In Bezug auf die Art, die ich habe .NET 4.5 installiert auf meiner box, aber ich habe nicht versuchen zu springen durch Reifen und machen es zu einem Teil meines Pakets Bereitstellung auf Azure. Das ist eine interessante Beobachtung.
  • Ich denke, die beste option ist jetzt einfach abwarten. Azure aktualisiert werden soll in diesem Monat nach ScottGu. In der Zwischenzeit, ich bin mit AppHarbor, die hatte .NET 4.5 unterstützen fast sofort.
  • Yep, ich habe schon sehnsüchtig darauf wartet seit RTW. Ich bin nur noch Kreuze meine Finger, dass Sie nicht lassen Sie die Rollen-basierte Bereitstellungen hinter sich, da Sie nur zu sein scheinen, reden, websites. Ich wollte sehen, @scottgu ' s post und habe meine Finger gekreuzt...
InformationsquelleAutor David Peden | 2012-10-19
Schreibe einen Kommentar