我正在调用一个速度缓慢的外部API。目前,如果我有一段时间没有调用API来获取一些订单,那么调用可以被分解为页面(分页(。
因此,获取订单可能需要多次调用,而不是一次调用。有时,每次通话可能需要10秒左右,所以总共可能需要一分钟左右,这太长了。
GetOrdersCall getOrders = new GetOrdersCall();
getOrders.DetailLevelList.Add(DetailLevelCodeType.ReturnSummary);
getOrders.CreateTimeFrom = lastOrderDate;
getOrders.CreateTimeTo = DateTime.Now;
PaginationType paging = new PaginationType();
paging.EntriesPerPage = 20;
paging.PageNumber = 1;
getOrders.Pagination = paging;
getOrders.Execute();
var response = getOrders.ApiResponse;
OrderTypeCollection orders = new OrderTypeCollection();
while (response != null && response.OrderArray.Count > 0)
{
eBayConverter.ConvertOrders(response.OrderArray, 1);
if (response.HasMoreOrders)
{
getOrders.Pagination.PageNumber++;
getOrders.Execute();
response = getOrders.ApiResponse;
orders.AddRange(response.OrderArray);
}
}
这是我上面代码的摘要。。。getOrders。Execute((是在api激发时执行的。
在第一个"getOrders.Execute(("之后有一个分页结果,它告诉有多少页数据。我的想法是,我应该能够为每个页面启动一个asnychronous调用,并填充OrderTypeCollection。当所有调用都完成并且集合已完全加载时,我将提交到数据库。
我以前从未通过c#进行过异步调用,我可以遵循Async wait,但我认为我的场景与我迄今为止所做的阅读不一样?
问题:
- 我想我可以将其设置为异步启动多个调用,但我不知道如何检查所有任务何时完成,即是否准备好提交到数据库
- 我在某个地方读到,我想避免将API调用和数据库写入结合起来,以避免在SQL server中锁定-这是正确的吗
如果有人能为我指明正确的方向,我将不胜感激。
我想我可以将其设置为异步启动多个调用但我不知道如何检查所有任务何时完成,即。准备提交到数据库。
是的,你可以分解
问题是ebay没有async Task Execute
方法,因此您只能阻塞线程调用,并且没有IO优化的异步等待模式。如果有的话,你可以利用TPL数据流管道,它是async
感知的(对全家来说很有趣(,无论如何,你都可以,尽管我提出了一个普通的TPL解决方案。。。
然而,并没有失去一切,只是回到Parallel.For
和ConcurrentBag<OrderType>
示例
var concurrentBag = new ConcurrentBag<OrderType>();
// make first call
// add results to concurrentBag
// pass the pageCount to the for
int pagesize = ...;
Parallel.For(1, pagesize,
page =>
{
// Set up
// add page
// make Call
foreach(var order in getOrders.ApiResponse)
concurrentBag.Add(order);
});
// all orders have been downloaded
// save to db
注意:您可以配置MaxDegreeOfParallelism
,可能会将其设置为50,尽管您给它多少并不重要,任务调度程序不会主动给您线程,最初可能会给您10个左右,并且增长缓慢。
另一种方法是创建自己的任务调度程序,或者使用老式的Thread
类启动自己的线程
我在某些地方读到,我想避免将API调用与数据库写入以避免在SQL server中锁定-这是正确的吗?
- 如果您的意思是锁定为慢速DB插入,请使用Sql大容量插入和更新工具
- 如果您的意思是像DB死锁错误消息中那样锁定,那么这是一件完全不同的事情,值得自己思考
其他资源
对于(Int32,Int32,ParallelOptions,Action(
执行一个for(Visual Basic中的for(循环,迭代可以在该循环中运行可以配置并行和循环选项。
ParallelOptions类
存储用于配置Parallel上方法操作的选项班
最大并行度
获取或设置此ParallelOptions实例。
ConcurrentBag类
表示线程安全、无序的对象集合。
是的,ConcurrentBag<T>
类可以用于为您的一个问题提供服务,该问题是:"我想我可以将其设置为异步启动多个调用,但我不知道如何检查所有任务何时完成,即准备提交到数据库。">
这个泛型类可用于运行每个任务,并等待所有任务完成以进行进一步处理。它是线程安全的,可用于并行处理。