从同步API迁移到异步API

时间:2019-04-03 01:03:39

标签: c# asynchronous

我需要从使用同步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完成,这与同步调用有何不同?

如果我进行以下更改并继续在SendWithRetries方法中调用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();
    }

为什么将async方法与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;
    }

2 个答案:

答案 0 :(得分:2)

  

与同步通话有何不同?

异步代码不会阻塞调用线程。

  

为什么将async方法与await结合使用比上述方法更好?

该方法将阻塞移动到线程池线程(Task.Run)。异步代码不会阻塞线程池线程。

  

另外,以下内容有什么问题

由于代码忽略了返回的Task,因此代码永远无法知道API调用何时完成,或者是否有错误。

更多信息:

答案 1 :(得分:0)

await关键字允许应用程序等待而不会变得无响应。当等待的操作在后台运行时,用户将能够继续与应用程序进行交互。操作完成后,默认情况下,UI线程中将执行await之后的代码。

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