2015-12-14 100 views
1

我正在构建一个应用程序,该应用程序将具有注册选项,并且我已经创建了一个方法来检查用户名是否可用,即异步。方法通过WebRequest连接到我的PHP/MySQL API并检索用户名是否被占用。Async WebRequest冻结应用程序

但是每当我试图在网上

var response = await webRequest.GetResponseAsync(); 

和整个应用程序运行该代码块只是冻结。尽管这样做同样的方法同步工作正常。

整体方法:

async public Task<UsernameAvailable> usernameAvailable() 
{ 
    try 
    { 
     token = "token=single"; 
     function = "&function=checkUser"; 
     string param = "&param=" + User.username; 

     string result = ""; 

     var webRequest = WebRequest.Create(@"http://" + APIURL + token + function + param); 
     var response = await webRequest.GetResponseAsync(); //troubled line 
     var content = response.GetResponseStream(); 
     StreamReader reader = new StreamReader(content); 

     result = reader.ReadLine(); 

     if (result == "0") 
     { 
      state = "Username is available."; 
      return UsernameAvailable.Available; 
     } 
     else 
     { 
      state = "Username is not available."; 
      return UsernameAvailable.NotAvailable; 
     } 
    } 
    catch 
    { 
     state = "Error checking for username."; 
     return UsernameAvailable.Error; 
    } 
} 
+0

* Synced *与*同步不同* –

+0

@MatíasFidemraizer它在上下文中。我已经更新了这个问题。 – DethoRhyne

+1

你是怎么调用'usernameAvailable'的? –

回答

5

我打算去胡乱猜测这里说,越往上你打电话usernameAvailable这样调用堆栈:

usernameAvailable().Result 

这是阻止异步代码,导致您的应用程序死锁。 This is why you shouldn't block on async code。原因your answer的工作原理是因为使用ConfigureAwait(false)阻止同步上下文继续下去,但这只是一个肮脏的解决方法,它掩盖了代码的实际问题。

而是这样做的,你也应该在你的方法使用异步事件处理程序和await还有:

public async void SomeEventHandler(object sender, EventArgs e) 
{ 
    await usernameAvailable(); 
} 

附注 - 异步方法应该有Async后缀添加到它们,所以你的方法应该实际上被命名为UsernameAvaliableAsync()

+0

你已经做到了!我已经使我的事件处理程序异步,添加在我正在运行检查的交换机内等待,它的工作原理应该如何!我对C#并不陌生,但在异步函数方面,我是一个很棒的noob。并感谢重命名提示。我也改了名字! :) – DethoRhyne

0

添加.ConfigureAwait(false)陷入困境的线固定的问题,现在一切工作正常!

老:

var response = await webRequest.GetResponseAsync(); 

固定:

var response = await webRequest.GetResponseAsync().ConfigureAwait(false); 
+1

您能否确认它与此处描述的死锁问题有关:http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html?如果是这样,请考虑链接此博客文章或(甚至更好)在你的答案中给出一个小的解释。 –

+1

@Abbondanza是的,我从该博客文章中添加了ConfigureAwait(false),但没有我可以发布的实际解释。我只是尝试了它在那里说了什么,然后以某种方式工作,但是,由于我在远程桌面会话中,后来我意识到它像一个普通的同步方法一样工作。 Yuval的答案是功能,它的功能是非同步的。 – DethoRhyne