2016-06-16 28 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()

所以編譯器知道的唯一事情就是你將一些lambda函數傳遞給該函數。但它無法推斷出它們何時會被執行。編譯器不知道Parallel.Invoke()僅在所有Action完成時纔會返回。它特別不知道你的lambda正在初始化變量。

因此,從編譯器的角度來看,即使在Parallel.Invoke()之後,您尚未將任何值分配給您的變量。

最簡單的方法是簡單地用默認值(null)手動initalize他們:

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

不要認爲這是原因,lambda表達式OP傳遞給'Parallel.Invoke()'不是'async'。即使'GetAll'返回了一個'Task',它應該被分配給變量。並且根據文檔'Parallel.Invoke'只有在所有'Action's完成時纔會返回。 –

+0

謝謝,但我得到一個編譯錯誤,說當我嘗試在等待之後使用它們時,這些變量是未分配的。 – moose56

+0

對不起,從我的頭頂快速轉換代碼到代碼片段,您可以像在自己的示例中那樣爲它們指定'null',我忽略了這一點。在lambda表達式中返回結果並捕獲Tasks結果可能會更好。但是,正如René指出的那樣,我假設你的操作在異步和這是造成問題的地方。 –