我正在尝试在针对.NET 4.0的MVC 4控制器操作中使用AsyncTargetingPack将一些信息异步记录到SQL Server。 我本可以直接跳转到.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()
我对异常没有任何可见性,因为它是所有外部代码。我不明白为什么第二段代码会失败。这是我最初编写的代码。
我做错了什么?
async
进行特殊支持,这是在.NET 4.5中添加的。我不建议在.NET 4.0的ASP.NET应用程序上尝试使用Async Targeting Pack - 一些简单的事情可能会起作用,但ASP.NET管道还没有准备好看到async
代码。 - Stephen Cleary