我有Web API方法調用另一個標有異步的方法來更新數據庫(使用EF 6)。我不需要等待數據庫方法來完成(它的火和遺忘),因此我調用這個異步方法時不使用await
。如果我不打電話給await
,則會拋出一個永遠不會傳遞給我的代碼的NullReferenceException,並且只是在VS2013的輸出窗口中顯示爲第一次機會異常。Web API異步異步方法
什麼是正確的方法來處理調用異步方法沒有await
-ing?
下面是一個例子我在做什麼:
數據回購方法:
public async Task UpdateSessionCheckAsync(int sessionId, DateTime time)
{
using (MyEntities context = new MyEntities())
{
var session = await context.Sessions.FindAsync(sessionId);
if (session != null)
session.LastCheck = time;
await context.SaveChangesAsync();
}
}
網絡API庫方法:
public async Task<ISession> GetSessionInfoAsync(int accountId, int siteId, int visitorId, int sessionId)
{
//some type of validation
var session =await GetValidSession(accountId, siteId, visitorId, sessionId);
DataAdapter.UpdateSessionCheckAsync(sessionId, DateTime.UtcNow); // this is the line causing the exception if not awaited
return new Session
{
Id = sessionId,
VisitorId = session.VisitorId
};
}
的Web API方法:
[ResponseType(typeof(Session))]
public async Task<IHttpActionResult> GetSessionInfo(HttpRequestMessage request, int accountId, int siteId, int visitorId, int sessionId)
{
var info = await _repository.GetSessionInfoAsync(accountId, siteId, visitorId, sessionId);
return Ok(info);
}
最後堆棧跟蹤我得到:
System.Web.dll!System.Web.ThreadContext.AssociateWithCurrentThread(bool setImpersonationContext)
System.Web.dll!System.Web.HttpApplication.OnThreadEnterPrivate(bool setImpersonationContext)
System.Web.dll!System.Web.HttpApplication.System.Web.Util.ISyncContext.Enter()
System.Web.dll!System.Web.Util.SynchronizationHelper.SafeWrapCallback(System.Action action)
System.Web.dll!System.Web.Util.SynchronizationHelper.QueueAsynchronous.AnonymousMethod__7(System.Threading.Tasks.Task _)
mscorlib.dll!System.Threading.Tasks.ContinuationTaskFromTask.InnerInvoke()
mscorlib.dll!System.Threading.Tasks.Task.Execute()
mscorlib.dll!System.Threading.Tasks.Task.ExecutionContextCallback(object obj)
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
mscorlib.dll!System.Threading.Tasks.Task.ExecuteWithThreadLocal(ref System.Threading.Tasks.Task currentTaskSlot)
mscorlib.dll!System.Threading.Tasks.Task.ExecuteEntry(bool bPreventDoubleExecution)
mscorlib.dll!System.Threading.Tasks.Task.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch()
mscorlib.dll!System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
編輯: 香港專業教育學院改變了我的分貝方法返回的任務,而不是無效,然後用Task.Factory啓動一個新的任務調用DB方法和異常消失了。
public async Task<ISession> GetSessionInfoAsync(int accountId, int siteId, int visitorId, int sessionId)
{
//some type of validation
var session =await GetValidSession(accountId, siteId, visitorId, sessionId);
Task.Factory.StartNew(() => DataAdapter.UpdateSessionCheckAsync(sessionId, DateTime.UtcNow));
return new Session
{
Id = sessionId,
VisitorId = session.VisitorId
};
}
請顯示一些代碼,包括例外的詳細信息。 –
@JonSkeet我已更新原始帖子。 –
[Fire and forget async method in asp.net mvc]可能的重複(http://stackoverflow.com/questions/18502745/fire-and-forget-async-method-in-asp-net-mvc) –