我正在连接到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