我是.NET Core
和异步编程的新手。我正在尝试实现一个控制台应用程序来执行以下操作:
下面是我的密码。它不像预期的那样起作用。最初,它按预期在10毫秒内调用API-1,但在此之后,它的调用API-1只在收到API-2的响应之后。
假设API-2需要20秒,API-1也在20秒后被调用.
如何使API-2调用异步,使其不必等待API-2响应?
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类
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服务中执行异步实现。
发布于 2016-08-12 01:20:41
在这种情况下,我会做很多不同的事情。与其使用计时器,我还会使用Task.Delay
--我肯定会等待API2完成,然后再尝试向它抛出更多的数据。此外,我将确保我的async
方法返回Task
或Task<T>
,注意您的CallAPI1
调用不是,我知道这是一个计时器回调--但这是另一个问题。
请考虑以下几点:
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);
}
}
这样做的方式如下:
最后,无论您是否使用.NET Core
,这都是相同的建议。任何API交互都应该遵循相同的准则。
Notes
在第二个API调用中使用失忆只会简单地将代码设置为失败。因为它是一个API调用,所以很可能会有一些I/O
绑定操作的延迟,人们应该假设10毫秒的紧循环只会淹没该端点上的可用性。为什么不简单地等待它完成,你可能有什么理由?
发布于 2016-08-11 23:58:48
调用API2时删除等待
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
这样,当API2失败时,您可以重放/重复作业。
https://stackoverflow.com/questions/38906813
复制相似问题