异步WebRequest冻结应用程序

时间:2015-12-14 09:03:18

标签: c# wpf asynchronous async-await task-parallel-library

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

但是每当我尝试在线上运行代码块时

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;
    }
}

2 个答案:

答案 0 :(得分:5)

我会在这里疯狂猜测,并说你正在调用的{(1}}更高的调用堆就像这样:

usernameAvailable

哪个阻止异步代码,导致您的应用死锁。 This is why you shouldn't block on async codeyour answer工作的原因是因为使用usernameAvailable().Result 会阻止同步上下文跟随延续,但这只是一个肮脏的解决方法,它可以解决代码的实际问题。

除了这样做之外,您还应该在方法上使用异步事件处理程序和ConfigureAwait(false)

await

附注 - 异步方法应该添加public async void SomeEventHandler(object sender, EventArgs e) { await usernameAvailable(); } 后缀,因此您的方法实际应该命名为Async

答案 1 :(得分:0)

在问题行中添加.ConfigureAwait(false)解决了问题,现在一切正常!

旧:

var response = await webRequest.GetResponseAsync(); 

固定:

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