【发布时间】:2019-04-19 20:14:28
【问题描述】:
我正在重构执行同步 http 请求并返回带有成功和失败事件的回调对象的旧代码。如何正确地将代码包装到 async/await 中?
我已经添加了 HttpClient 类,并且我正在使用我等待的 SendAsync 方法,但我不确定如何正确地从等待过渡到事件。我在类中添加了 async void Execute 方法,但它似乎不是正确的处理方式 - 避免使用 async void。下面是(短版)代码中的更多解释。
public class HttpExecutor(){
public event Action<string> Succeed;
public event Action<ErrorType, string> Failed;
private bool isExecuting;
//I know that async void is not the best because of exceptions
//and code smell when it is not event handler
public async void Execute()
{
if (isExecuting) return;
isExecuting = true;
cancellationTokenSource = new CancellationTokenSource();
try
{
httpResponseMessage =
await httpService.SendAsync(requestData, cancellationTokenSource.Token).ConfigureAwait(false);
var responseString = string.Empty;
if (httpResponseMessage.Content != null)
{
responseString = await httpResponseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
}
if (httpResponseMessage.IsSuccessStatusCode)
{
Succeed?.Invoke(responseString);
return;
}
Failed?.Invoke(httpResponseMessage.GetErrorType(),
$"{httpResponseMessage.ReasonPhrase}\n{responseString}");
}
//Catch all exceptions separately
catch(...){
}
finally
{
Dispose();
}
}
}
public class UserService(){
public CallbackObject<User> GetUser(){
var executor = new HttpExecutor(new RequestData());
//CallbackObject has also success and fail, and it hooks to executor events, deserializes string into object and sends model by his own events.
var callback = new CallbackObject<User>(executor);
executor.Execute();//in normal case called when all code has possibility to hook into event
return callback;
}
}
我觉得我应该将方法更改为:public async Task ExecuteAsync(){...},但是我需要通过执行以下操作从线程池中获取线程:Task.Run(()=>executor.ExecuteAsync());
这似乎有点过时了,但有回调(我等待来自网络的响应)。如何正确处理?
【问题讨论】:
-
在体验了 async/await 的精彩之后,为什么还要回到回调? :-)。
-
您有什么理由需要这些操作吗?最初的用例是释放 UI 以提高响应能力吗?
-
"但是我需要从线程池中获取线程" - 为什么?
标签: c# asynchronous async-await request void