简体   繁体   English

异步方法不返回

[英]Async Method Doesn't Return

I have the following Action method that uses Scanner class which uses some webservice to get some data. 我有以下Action方法,它使用Scanner类,它使用一些webservice来获取一些数据。 When I use breakpoint inside GetSuggestions method, I can see the result. 当我在GetSuggestions方法中使用断点时,可以看到结果。 However, this data is never returned to my Action method. 但是,此数据永远不会返回到我的Action方法。 Instead when I check the value of model inside Index() , it is, 相反,当我检查Index()model的值时,它是,

Id = 1, Status = System.Threading.Tasks.TaskStatus.WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"

I checked this question but It did not helped me. 我检查了这个问题,但它没有帮助我。

Controller Action Method: 控制器动作方法:

[HttpGet]
public ActionResult Index()
{
    var plane = new Scanner();
    var model = plane.GetSuggestions("ISTANBUL");

    return View(model);
}

GetSuggestions Method : 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 Method : RequestProvider方法:

public static async Task<string> Get(string url)
{
    using (var client = new HttpClient())
    {
        return await client.GetStringAsync(url);
    }
}

Edit 1 编辑1

I also tried wrapping the Action method with task and waiting on GetSuggestions method but I receive exception on client.GetStringAsync(url) 我也尝试用Action包装Action方法并等待GetSuggestions方法,但我在client.GetStringAsync(url)上收到异常

Exception When I use Task on Action Method 当我在“操作方法”上使用“任务”时发生异常

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: 

Edit 2 编辑2

I removed the await keyword from await client.GetStringAsync(url); 我从await client.GetStringAsync(url);删除了await关键字await client.GetStringAsync(url); and code works. 和代码工作。 However, I think this will run synchronously not async. 但是,我认为这将同步运行而不是异步运行。 Following is the updated Get method, 以下是更新的Get方法,

public static async Task<string> Get(string url)
{
    using (var client = new HttpClient())
    {
        return client.GetStringAsync(url).Result;
    }  
}

There are two parts to your problem. 你的问题分为两部分。

The first is the deadlock. 首先是僵局。 You need to replace any Task.Wait or Task<T>.Result calls with await . 您需要使用await替换任何Task.WaitTask<T>.Result调用。 I explain this deadlock scenario more fully on my blog and in the answer you linked to . 在博客您链接的答案中更充分地解释了这种死锁情况。

The second is the exception. 第二个例外。 You're seeing this exception because you're using async / await on ASP.NET 4.0, which is not supported. 您正在看到此异常,因为您在ASP.NET 4.0上使用async / await ,这是不受支持的。 You need to ensure that you're targeting .NET 4.5 and that you have set <httpRuntime targetFramework="4.5" /> in your web.config . 您需要确保以.NET 4.5为目标,并在web.config中设置<httpRuntime targetFramework="4.5" />

I think you need to await on the call to plane.GetSuggestions("ISTANBUL"); 我想你需要等待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);
}

When you're debugging the code, it likely is wokring as expected, since you are stepping through the code. 当您调试代码时,由于逐步执行代码,它可能会按预期运行。 Howver, once you let the code run naturally, since the call to plane.GetSuggestions("ISTANBUL"); 一旦你让代码自然运行,自从调用plane.GetSuggestions("ISTANBUL"); is not awaiting, and thus goes ahead and calls return View(model); 是等待,因此继续调用return View(model); before plane.GetSuggestions("ISTANBUL"); plane.GetSuggestions("ISTANBUL"); has had a chance to finish. 有机会完成。

I think that's why you're not getting the expected result. 我认为这就是为什么你没有得到预期的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM