从同步 API 迁移到异步 API



我需要从使用同步 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 线程中执行。

您可能需要在等待操作期间限制用户进行某些交互。某些按钮或菜单选项最好禁用,以便用户无法启动多个异步操作,并导致资源匮乏或其他问题。

最新更新