首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用.NET核心进行异步编程?

用.NET核心进行异步编程?
EN

Stack Overflow用户
提问于 2016-08-11 22:03:43
回答 2查看 8.4K关注 0票数 0

我是.NET Core和异步编程的新手。我正在尝试实现一个控制台应用程序来执行以下操作:

  1. 控制台应用程序应该在两个外部API之间充当中介。例如:API-1和API-2.
  2. 它应该在每10毫秒之后调用API-1来获取数据。
  3. 立即调用API-2提交从API-1接收的数据。
  4. Console Application需要等待API-1接收数据,但不必等待API-2的响应。

下面是我的密码。它不像预期的那样起作用。最初,它按预期在10毫秒内调用API-1,但在此之后,它的调用API-1只在收到API-2的响应之后。

假设API-2需要20秒,API-1也在20秒后被调用.

如何使API-2调用异步,使其不必等待API-2响应?

代码语言:javascript
运行
复制
namespace ConsoleApp1
{
    public class Program
    {
        private static Timer _timer;
        private const int TIME_INTERVAL_IN_MILLISECONDS = 10; // 10 milliseconds
        private const int API2_DELAY = 20000; // 20 seconds
        public static void Main(string[] args)
        {
            Dowork().Wait();
            Console.WriteLine("Press Any Key to stop");
            Console.ReadKey();
            Console.WriteLine("Done");
        }

        private static async Task Dowork()
        {
            var data = new SomeData();
            _timer = new Timer(CallAPI1, data, TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite);
            await Task.Yield();            
        }

        private static async void CallAPI1(object state)
        {           
            var data = state as SomeData;

            Console.WriteLine("Calling API One to get some data.");
            data.SomeStringValue = DateTime.Now.ToString();

            await CallAPI2(data);
            _timer.Change(TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite);
        }

        private static async Task CallAPI2(SomeData data)
        {           
            Console.WriteLine("Calling API Two by passing some data received from API One " + data.SomeStringValue);

            // the delay represent long running call to API 2
            await Task.Delay(API2_DELAY);
        }
    }
}

POCO类

代码语言:javascript
运行
复制
namespace ConsoleApp1
{
    public class SomeData
    {
        public string SomeStringValue { get; set; }
    }
}

还请注意,API-1和API-2将在ASP.NET Core 1中开发。

Update1

让我改一句上面的句子。API-1将在.Net核心中开发,而API-2将是windows工作流服务.这意味着我们可以给WF打多个电话。WF将持久化请求并一次处理一个请求。

Update2

经过所有的答案和提供的链接。我正在考虑使用windows服务作为中介,而不是控制台应用程序。现在,.Net core不支持窗口服务,但是这个坚果包装可以在windows服务中承载.Net核心,或者我可以使用4.6.2使用经典的windows服务。我想我也可以在windows服务中执行异步实现。

EN

回答 2

Stack Overflow用户

发布于 2016-08-12 01:20:41

在这种情况下,我会做很多不同的事情。与其使用计时器,我还会使用Task.Delay --我肯定会等待API2完成,然后再尝试向它抛出更多的数据。此外,我将确保我的async方法返回TaskTask<T>,注意您的CallAPI1调用不是,我知道这是一个计时器回调--但这是另一个问题。

请考虑以下几点:

代码语言:javascript
运行
复制
async Task IntermediateAsync()
{
    Console.WriteLine("Press ESC to exit...");

    while (Console.ReadKey(true).Key != ConsoleKey.Escape)
    {
        var result = await _apiServiceOne.GetAsync();
        await _apiServiceTwo.PostAsync(result);

        // Wait ten milliseconds after each successful mediation phase
        await Task.Delay(10);
    }
}

这样做的方式如下:

  1. 打印一行,指示用户如何退出
  2. 起动回路
  3. 得到API1的结果
  4. 将结果传递给API2
  5. 等待10毫秒
  6. 第二步

最后,无论您是否使用.NET Core,这都是相同的建议。任何API交互都应该遵循相同的准则。

Notes

在第二个API调用中使用失忆只会简单地将代码设置为失败。因为它是一个API调用,所以很可能会有一些I/O绑定操作的延迟,人们应该假设10毫秒的紧循环只会淹没该端点上的可用性。为什么不简单地等待它完成,你可能有什么理由?

票数 2
EN

Stack Overflow用户

发布于 2016-08-11 23:58:48

调用API2时删除等待

代码语言:javascript
运行
复制
    private static async void CallAPI1(object state)
    {
        var data = state as SomeData;

        Console.WriteLine("Calling API One to get some data.");
        data.SomeStringValue = DateTime.Now.ToString();
        //Before this will cause the program to wait
        await CallAPI2(data);
        // Now it will call and forget
        CallAPI2(data);
        _timer.Change(TIME_INTERVAL_IN_MILLISECONDS, Timeout.Infinite);
    }

编辑:

正如大卫所指出的,当然有很多方法来解决这个问题。这不是解决问题的正确方法。

另一种做事的方法是使用quartz.net

  1. 将API1调度为重复作业
  2. 完成API1后,将另一项任务安排为独立作业运行API2

这样,当API2失败时,您可以重放/重复作业。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38906813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档