我的RestSharp实现存在以下问题。在继续之前,如何让我的应用程序等待来自ExecuteAsync()
的响应?
我尝试了不同的解决方案:
首先(该方法不等待ExecuteAsync响应):
public Task<Connection> Connect(string userId, string password)
{
var client = new RestClient(_baseUrl)
{
Authenticator = new SimpleAuthenticator("user", userId,
"password", password)
};
var tcs = new TaskCompletionSource<Connection>();
var request = new RestRequest(AppResources.Authenticating);
client.ExecuteAsync<Connection>(request, response =>
{
tcs.SetResult(new JsonDeserializer().
Deserialize<Connection>(response));
});
return tcs.Task;
}
所以我尝试了这个,但应用程序冻结了:
public Task<Connection> Connect(string userId, string password)
{
EventWaitHandle executedCallBack = new AutoResetEvent(false);
var client = new RestClient(_baseUrl)
{
Authenticator = new SimpleAuthenticator("user", userId,
"password", password)
};
var tcs = new TaskCompletionSource<Connection>();
var request = new RestRequest(AppResources.Authenticating);
client.ExecuteAsync<Connection>(request, response =>
{
tcs.SetResult(new JsonDeserializer().
Deserialize<Connection>(response));
executedCallBack.Set();
});
executedCallBack.WaitOne();
return tcs.Task;
}
答案 0 :(得分:4)
我认为你忽略了Task和async / await模式的重点。
你不要在这个方法中等待,但因为你正在返回Task<>
,它允许调用者在选择时异步等待它。
来电者会是这样的:
public async void ButtonClick(object sender, RoutedEventArgs args)
{
Connection result = await restClient.Connect(this.UserId.Text, this.Password.Text);
//... do something with result
}
编译器知道如何创建此代码,这与同步(阻塞)等效代码非常相似,并将其转换为异步代码。
请注意async
和await
个关键字,并注意Task<Connection>
已转入Connection
。
鉴于:您的第一个代码段看起来没问题。
当您引入另一种线程机制(即信号量AutoResetEvent
)时,第二种可能会引发问题。另外@HaspEmulator是正确的 - 如果这是在UI线程上,则知道这会使WP应用程序死锁。
答案 1 :(得分:0)
这看起来非常类似于周围很多人的问题:在执行WebRequest时(直接或间接通过其他一些库)不应该阻塞。它似乎陷入僵局。避免这种情况。