异步日志记录抛出NullReferenceException

我试图使用AsyncTargetingPack异步将一些信息记录到针对.NET 4.0的MVC 4控制器操作中的SQL Server。 我会直接跳到.NET 4.5,但我的应用程序存在于Azure中, 我们仍在等待更新 …

此代码按预期工作(一行写入我的数据库,没有抛出exception):

public class SystemActionLogger : ISystemActionLogger { private readonly ActionBlock<Tuple> actionBlock; public SystemActionLogger(ISystemActionLogEntryRepository repository) { actionBlock = new ActionBlock<Tuple>( 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, data)); } } 

并且此代码抛出NullReferenceException:

 public class SystemActionLogger : ISystemActionLogger { private readonly ActionBlock<Tuple> actionBlock; public SystemActionLogger(ISystemActionLogEntryRepository repository) { actionBlock = new ActionBlock<Tuple>(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, 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.b__0(Task param0) Exception rethrown at [0]: at System.Runtime.CompilerServices.AsyncMethodBuilderCore.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() 

我没有对exception的可见性,因为它是所有外部代码。 我不明白为什么第二个代码块失败。 这是我最初写的代码。

我究竟做错了什么?

我只是遇到了一个非常类似的问题(使用日志记录任务时来自AssociateWithCurrentThread的NullReference)。

我遇到的问题是原始操作没有等待日志记录任务的完成,所以当日志完成并尝试重新加入原始线程时,抛出nullReference,因为原始线程已终止。

这是通过确保请求控制器等待日志记录function来解决的。

Dataflow仅适用于.NET 4.5。 您在.NET 4.0上运行它的事实是不受支持的,这可能是您看到虚假exception的原因。

当我的Web服务以异步方式调用另一个WCF服务时,我遇到了.net4.5这个问题。 我只是附加了一个短时间的Wait()因为我不关心响应(遥测事件)。

 public static void Event(string key, string message) { Telemetry.Event(key, message).Wait(100); }