[英]Async and await: Why doesn't an async method whose signature defines a return type of Task explicitly return a Task?
[英]Async Method Doesn't Return
我有以下Action方法,它使用Scanner
類,它使用一些webservice來獲取一些數據。 當我在GetSuggestions
方法中使用斷點時,可以看到結果。 但是,此數據永遠不會返回到我的Action方法。 相反,當我檢查Index()
的model
的值時,它是,
Id = 1, Status = System.Threading.Tasks.TaskStatus.WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"
我檢查了這個問題,但它沒有幫助我。
控制器動作方法:
[HttpGet]
public ActionResult Index()
{
var plane = new Scanner();
var model = plane.GetSuggestions("ISTANBUL");
return View(model);
}
GetSuggestions方法:
public async Task<List<PlaceDto>> GetSuggestions(string key)
{
string url = String.Format("URL GOES HERE", key, API_KEY);
string data = await RequestProvider.Get(url);
return JObject.Parse(data).SelectToken("Places").ToObject<List<PlaceDto>>();
}
RequestProvider方法:
public static async Task<string> Get(string url)
{
using (var client = new HttpClient())
{
return await client.GetStringAsync(url);
}
}
編輯1
我也嘗試用Action包裝Action方法並等待GetSuggestions
方法,但我在client.GetStringAsync(url)
上收到異常
當我在“操作方法”上使用“任務”時發生異常
System.NullReferenceException was unhandled
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=System.Web
StackTrace:
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.Web.LegacyAspNetSynchronizationContext.Post(SendOrPostCallback callback, Object state)
at System.Threading.Tasks.SynchronizationContextAwaitTaskContinuation.PostAction(Object state)
at System.Threading.Tasks.AwaitTaskContinuation.RunCallback(ContextCallback callback, Object state, Task& currentTask)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.AwaitTaskContinuation.<ThrowAsyncIfNecessary>b__1(Object s)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(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()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
InnerException:
編輯2
我從await client.GetStringAsync(url);
刪除了await關鍵字await client.GetStringAsync(url);
和代碼工作。 但是,我認為這將同步運行而不是異步運行。 以下是更新的Get方法,
public static async Task<string> Get(string url)
{
using (var client = new HttpClient())
{
return client.GetStringAsync(url).Result;
}
}
你的問題分為兩部分。
首先是僵局。 您需要使用await
替換任何Task.Wait
或Task<T>.Result
調用。 我在博客和您鏈接的答案中更充分地解釋了這種死鎖情況。
第二個例外。 您正在看到此異常,因為您在ASP.NET 4.0上使用async
/ await
,這是不受支持的。 您需要確保以.NET 4.5為目標,並在web.config中設置<httpRuntime targetFramework="4.5" />
。
我想你需要等待plane.GetSuggestions("ISTANBUL");
的召喚plane.GetSuggestions("ISTANBUL");
[HttpGet]
public async Task<ActionResult> Index()
{
var plane = new Scanner();
var model = await plane.GetSuggestions("ISTANBUL");
return View(model);
}
當您調試代碼時,由於逐步執行代碼,它可能會按預期運行。 一旦你讓代碼自然運行,自從調用plane.GetSuggestions("ISTANBUL");
是等待,因此繼續調用return View(model);
在plane.GetSuggestions("ISTANBUL");
有機會完成。
我認為這就是為什么你沒有得到預期的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.