我需要从使用同步 API 转向异步 API:
void Client()
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
int numAttempts = SendWithRetries();
stopWatch.Stop();
Logging.Log(LoggingLevel.Info, string.Format("time taken {0} ", numEvents, partitionId, stopWatch.Elapsed.TotalSeconds.ToString()));
}
private int SendWithRetries(int numRetries = 3)
{
for (int i = 0; i <= numRetries; i++)
{
try
{
API();
return i;
}
catch (Exception e)
{
if (i == numRetries)
{
throw;
}
}
}
return -1;
}
现在要迁移到异步API,我从互联网上收集到我需要替换API的信息
await APIAsync()
我对此有点困惑。当我添加 await 时,它会强制主线程等待 APIAsync 完成这与同步调用有何不同?
如果我进行以下更改并继续在 SendWithRetry 方法中调用 API(( 怎么办:
void Client()
{
Task newTask =
System.Threading.Tasks.Task.Run(() => {
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
int numAttempts = SendWithRetries();
stopWatch.Stop();
Logging.Log(LoggingLevel.Info, string.Format("### time taken {0} ", numEvents, partitionId, stopWatch.Elapsed.TotalSeconds.ToString()));
});
newTask.Wait();
}
为什么将异步方法与 await 一起使用比上述方法更好?
另外,以下内容有什么问题:
private int SendWithRetries(int numRetries = 3)
{
for (int i = 0; i <= numRetries; i++)
{
try
{
APIAsync();
return i;
}
catch (Exception e)
{
if (i == numRetries)
{
throw;
}
}
}
return -1;
}
这与同步调用有何不同?
异步代码不会阻止调用线程。
为什么将异步方法与 await 一起使用比上述方法更好?
这种方法将阻塞移动到线程池线程(Task.Run
(。异步代码不会阻塞线程池线程。
另外,以下内容有什么问题
由于代码忽略返回的Task
,代码永远无法知道 API 调用何时完成,或者是否有错误。
更多信息:
- 异步和等待
- 异步最佳实践
await
关键字允许应用程序等待而不会变得无响应。用户将能够继续与应用程序交互,同时等待的操作在后台运行。操作完成后,默认情况下,await 之后的代码将在 UI 线程中执行。
您可能需要在等待操作期间限制用户进行某些交互。某些按钮或菜单选项最好禁用,以便用户无法启动多个异步操作,并导致资源匮乏或其他问题。