Ich versuche, einige Informationen zu SQL Server innerhalb einer MVC 4-Controller-Aktion, die .NET 4.0 mit dem AsyncTargetingPack abzielt, zu protokollieren. Ich würde gehen Sie direkt zu .NET 4.5, aber mein App lebt in Azure und we're still waiting for the update ...Async-Protokollierung, die eine NullReferenceException wirft
Dieser Code funktioniert wie erwartet (eine Zeile zu meiner Datenbank ohne Ausnahmen geworfen geschrieben):
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 führt eine 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: „der Objektverweis auf eine Instanz eines Objekts nicht gesetzt“
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 keine Sichtbarkeit in der Ausnahme, da es alle externen Code ist. Ich verstehe nicht, warum der zweite Codeblock fehlschlägt. Dies ist der Code, den ich ursprünglich geschrieben habe.
Was mache ich falsch?
ASP.NET benötigt spezielle Unterstützung für 'async', die in .NET 4.5 hinzugefügt wurde. Ich würde nicht versuchen, das Async Targeting Pack für ASP.NET-Anwendungen für .NET 4.0 zu verwenden - ein paar einfache Dinge würden funktionieren, aber die ASP.NET-Pipeline ist einfach nicht bereit, Async-Code zu sehen. –
Ihr Stack-Trace enthält einen Verweis auf "LegacyAspNetSynchronizationContext", ein in .NET 4.5 hinzugefügter Typ. Haben Sie .NET 4.5 auf Ihrem Azure-Server installiert? –
Hey Stephen, danke für die Antwort. Ich hatte eine ähnliche Antwort von dir auf einem anderen SO Post gesehen und gehofft, dass dies nicht der Fall war, besonders seit der erste Code funktioniert. Bezüglich des Typs habe ich .NET 4.5 auf meiner Box installiert, aber ich habe nicht versucht, durch die Rahmen zu springen und es zu einem Teil meines Bereitstellungspakets für Azure zu machen. Das ist eine interessante Beobachtung. –