并行运行一系列方法



我正在连接到REST API并调用多个端点以获取不同的对象。我为要下载的每种类型创建一个RestService<T>

RestService<Agent> agentService = new RestService<Agent>(auth, new AgentApi());
RestService<Ticket> ticketService = new RestService<Ticket>(auth, new TicketApi());
RestService<Company> companyService = new RestService<Company>(auth, new CompanyApi());
RestService<Contact> contactService = new RestService<Contact>(auth, new ContactApi());

对于每个RestService<T>,我都会调用GetAll()来调用 REST API 并获取结果:

RestResult<Agent> agentResults = agentService.GetAll();
RestResult<Company> companyResults = companyService.GetAll();
RestResult<Contact> contactResults = contactService.GetAll();
RestResult<Ticket> ticketResults = ticketService.GetAll();

在幕后,GetAll()进行了多次HttpWebRequest追查。

所以我的想法是以某种方式并行调用 4 个GetAll()调用,因为理论上我可以向 REST API 发出多个请求,而不是一个接一个地请求。

我的一个想法是:

RestResult<Agent> agentResults;
RestResult<Company> companyResults;
RestResult<Contact> contactResults;
RestResult<Ticket> ticketResults;
Parallel.Invoke(
() => agentResults = agentService.GetAll(),
() => companyResults = companyService.GetAll(),
() => contactResults = contactService.GetAll(),
() => ticketResults = ticketService.GetAll()
);

但看起来变量从未初始化过。

关于如何处理这个问题的任何建议?

编译器警告您变量未初始化,因为编译器不理解Parallel.Invoke()语义

因此,编译器唯一知道的是您将一些 lambda 传递给该函数。但它无法推断它们何时会被执行。编译器不知道Parallel.Invoke()仅在所有Action都完成后返回。它尤其不知道您的 lambda 正在初始化变量。

因此,从编译器的角度来看,即使在Parallel.Invoke()之后,您也没有为变量分配任何值。

最简单的解决方案是简单地使用默认值(null)手动启动它们:

RestResult<Agent> agentResults = null;
RestResult<Company> companyResults = null;
RestResult<Contact> contactResults = null;
RestResult<Ticket> ticketResults = null;
Parallel.Invoke(
() => agentResults = agentService.GetAll(Epoch),
() => companyResults = companyService.GetAll(Epoch),
() => contactResults = contactService.GetAll(Epoch),
() => ticketResults = ticketService.GetAll(Epoch)
);

看看这个问题,似乎和你遇到的问题是一样的。Parallel.Invoke 似乎不等待异步操作。请改用 Task.WhenAll 等待所有任务完成: Parallel.Invoke 不等待异步方法完成

RestResult<Agent> agentResults;
RestResult<Company> companyResults;
RestResult<Contact> contactResults;
RestResult<Ticket> ticketResults;
var t1 = Task.Run(() => agentResults = agentService.GetAll(Epoch))
var t2 = Task.Run(() => companyResults = companyService.GetAll(Epoch));
var t3 = Task.Run(() => contactResults = contactService.GetAll(Epoch));
var t4 = Taks.Run(() => ticketResults = ticketService.GetAll(Epoch));
await Task.WhenAll(t1,t2,t3,t4);
//results should be filled here

相关内容

最新更新