2016-06-16 2 views
0

Я подключаюсь к 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 resquests.

Так что я думаю, так или иначе вызвать вызовы 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() 
); 

Но, похоже, переменные никогда не инициализируются.

Любые предложения о том, как подойти к этому?

+0

Что «это выглядит как» означает? Они все еще «нулевые»? Если да, уверены ли вы, что методы 'GetAll()' вернули что-то еще? –

+0

Извините, я имел в виду, что я получаю ошибку компиляции, говоря, что переменные не назначены, когда я пытаюсь их использовать позже. – moose56

ответ

2

Вы компилятор предупреждает вас о том, что переменные не инициализируются, потому что компилятор не понимает семантику из Parallel.Invoke().

Итак, единственное, что знает компилятор, это то, что вы передаете некоторые лямбды этой функции. Но он не может сделать вывод, когда они будут выполнены. Компилятор не знает, что Parallel.Invoke() возвращается только после завершения всех Action. И это особенно не знает, что ваши лямбды инициализируют переменные.

С точки зрения компилятора, даже после 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) 
); 
+0

Спасибо, я не был уверен, что я что-то упустил. – moose56

1

Посмотрите на эти вопросы, похоже на ту же проблему, что и у вас. Parallel.Invoke, похоже, не ждет асинхронных операций. Вместо того, чтобы использовать Task.WhenAll ждать все задачи для завершения: Parallel.Invoke does not wait for async methods to complete

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 
+0

Не думайте, что это причина, lambdas OP переходит в 'Parallel.Invoke()' _not_ 'async'. Даже если 'GetAll' возвращает' Task', это должно быть назначено переменным. И согласно документации 'Parallel.Invoke' возвращается только в том случае, если все' Action 'были завершены. –

+0

Спасибо, но я получаю ошибку компиляции, говоря, что переменные не назначены, когда я пытаюсь использовать их позже после ожидания. – moose56

+0

Извините, что это было просто с самого начала, превратив ваш код в фрагмент, вы можете присвоить их «null», как это было в вашем собственном примере, я упустил это. Вероятно, было бы лучше вернуть результат в выражении лямбда и получить результаты Задачи. Но, как заметил Рене, я предположил, что вы делаете асинхронный процесс и что это вызывает проблему. –

Смежные вопросы