【问题标题】:Calling an API sync or async?调用 API 同步还是异步?
【发布时间】:2019-04-15 05:41:09
【问题描述】:

我正在尝试使用我在 NODE.js 中开发的 API,我是从 c# windows 窗体桌面应用程序中执行此操作的。

API 是在服务器端异步编写的,但它可以在我的客户端内同步吗?让我解释一下我的意思。

这是我正在做的代码示例:

public static DateTime GetDateTime()
{
    try
   {
        string result = Task.Run(() => 
        client.GetStringAsync(client.BaseAddress)).Result;
        Date currentTime = JsonConvert.DeserializeObject<Date>(result);
        return currentTime.Value;
    }
   catch (Exception ex)
   {
       throw ex;
   }

}  

稍后在程序中我调用了这个函数:

DateTime currentDate = GymAPI.GetDateTime();

根据我的研究,这是同步运行的......这就是我需要的,因为在函数调用之后,我使用日期时间来计算和显示人员列表的年龄。

据我了解,如果我使用 ASYNC/AWAIT,计算人员年龄的代码将立即执行,而我很可能还没有当前日期的值。我的假设是否正确?

我是否需要在我的应用程序中运行任何 ASYNC,而不是在我发送电子邮件时(大约需要 5 秒)并且我希望 sendmail 任务在后台运行,同时应用程序保持对用户的响应?

最后,更重要的是,上面的代码似乎可以工作,但是……我这样做的方式是使调用同步运行的最佳做法吗?没有死锁?感谢您耐心阅读本文,但我发现了很多帖子,老实说我找不到所有答案。

如果问题太多,请只回答最后一个! :)

【问题讨论】:

  • 单个 StackOverflow 问题的问题太多。
  • 不,异步并不意味着代码会继续执行而不等待调用结果。
  • var result = Task.Run(() =&gt; DoSomethingAsync()).Result; 可能会在各种情况下导致死锁。 "c# run async method synchronously" 谷歌一下。
  • 如果您想要同步执行的唯一原因是因为您认为代码将继续运行而不是等待,请不要。它会等待,这就是await 的全部意义所在。只需使用异步方式,不要试图强制它同步。除非client 有一个同步方法,通常情况也是如此。服务器端也无所谓,它可以是同步或异步的,客户端可以为所欲为。

标签: c# api async-await task desktop-application


【解决方案1】:

所以我从根本上感到困惑,我没有掌握 ASYNC/AWAIT/TASK 的关系……但现在我想清楚多了。

我遵循了建议并按照此链接中的示例采用了 ASYNC 方式:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

如果有人关心,我会像这样重写所有内容:

        public static async Task<DateTime>GetDateTime()
        {
            using (HttpClient client = new HttpClient())
            {
                // Omitted some code here for simplicity.
                try
                {
                    string result = await client.GetStringAsync(client.BaseAddress);
                    Date currentTime = JsonConvert.DeserializeObject<Date>(result);
                    return currentTime.Value;
                }
                catch (Exception ex)
                {
                    throw ex;
                }

            }
        }

基本上,您可以异步运行任务,因此当您调用函数 GetDateTime() 时,您将开始运行任务,而不会像这样阻止下面的代码执行:

Task<DateTime> getCurrentDate = MyClass.GetDateTime();
//Code here executes right away without waiting for the task to finish

在这种情况下,我在构造函数中启动了任务,并在我需要这样的结果之前等待它:

DateTime result = await getCurrentDate;

或者您可以在同一行代码中开始并等待任务完成:

DateTime result = await MyClass.getCurrentDate();

使用上面的方法,它看起来是同步的,但是您并没有真正利用在执行其他代码的同时运行一个或多个任务。

【讨论】:

  • 你还是very much missing the point。您将阻塞与并行处理混淆了,它们不是一回事
  • @Liam 感谢您的链接,我阅读了它,他们主要讨论等待与等待。我想我明白你的意思了,说非阻塞代码实际上是一个并行过程,但我在这里了解了更多关于此的更多信息 stackoverflow.com/questions/2625493/… 再次感谢您的输入。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多