Async WebRequest 冻结应用程序
Async WebRequest freezes application
我正在构建一个将具有注册选项的应用程序,并且我已经创建了一个检查用户名是否可用的方法,该方法是异步的。方法通过 WebRequest 连接到我的 PHP/MySQL API 并检索用户名是否被占用。
但是每当我尝试运行这个代码块时
var response = await webRequest.GetResponseAsync();
并且整个应用程序都冻结了。不过,同步执行相同的方法效果很好。
整个方法:
async public Task<UsernameAvailable> usernameAvailable()
{
try
{
token = "token=single";
function = "&function=checkUser";
string param = "¶m=" + 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;
}
}
将 .ConfigureAwait(false)
添加到有问题的线路解决了问题,现在一切正常!
旧:
var response = await webRequest.GetResponseAsync();
固定:
var response = await webRequest.GetResponseAsync().ConfigureAwait(false);
我将在这里进行大胆的猜测,并说您正在调用 usernameAvailable
的调用堆栈更高层,如下所示:
usernameAvailable().Result
阻塞异步代码,导致您的应用程序死锁。 This is why you shouldn't block on async code. The reason 有效是因为使用 ConfigureAwait(false)
阻止了同步上下文跟随继续,但这只是一个肮脏的解决方法,它掩盖了代码的实际问题。
除此之外,您还应该在方法中使用异步事件处理程序和 await
:
public async void SomeEventHandler(object sender, EventArgs e)
{
await usernameAvailable();
}
旁注 - 异步方法应添加 Async
后缀,因此您的方法实际上应命名为 UsernameAvaliableAsync()
我正在构建一个将具有注册选项的应用程序,并且我已经创建了一个检查用户名是否可用的方法,该方法是异步的。方法通过 WebRequest 连接到我的 PHP/MySQL API 并检索用户名是否被占用。
但是每当我尝试运行这个代码块时
var response = await webRequest.GetResponseAsync();
并且整个应用程序都冻结了。不过,同步执行相同的方法效果很好。
整个方法:
async public Task<UsernameAvailable> usernameAvailable()
{
try
{
token = "token=single";
function = "&function=checkUser";
string param = "¶m=" + 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;
}
}
将 .ConfigureAwait(false)
添加到有问题的线路解决了问题,现在一切正常!
旧:
var response = await webRequest.GetResponseAsync();
固定:
var response = await webRequest.GetResponseAsync().ConfigureAwait(false);
我将在这里进行大胆的猜测,并说您正在调用 usernameAvailable
的调用堆栈更高层,如下所示:
usernameAvailable().Result
阻塞异步代码,导致您的应用程序死锁。 This is why you shouldn't block on async code. The reason ConfigureAwait(false)
阻止了同步上下文跟随继续,但这只是一个肮脏的解决方法,它掩盖了代码的实际问题。
除此之外,您还应该在方法中使用异步事件处理程序和 await
:
public async void SomeEventHandler(object sender, EventArgs e)
{
await usernameAvailable();
}
旁注 - 异步方法应添加 Async
后缀,因此您的方法实际上应命名为 UsernameAvaliableAsync()