我有這條線,它不阻塞(同步)Web服務調用,並正常工作:如何取消RestSharp同步execute()調用?
var response = client.Execute<DataRequestResponse>(request);
(該var
代表IRestResponse<DataRequestResponse>
)
但是,現在我希望能夠取消它(來自另一個線程)。 (我發現這個similar question,但我的代碼必須保持同步 - 代碼修改在這個函數保持本地化。)
我發現CancellationTokenSource
和ExecuteTaskAsync()
,這需要CancellationToken
。 (見https://stackoverflow.com/a/21779724/841830)這聽起來像可以完成這項工作。我得到了這樣的代碼:
var cancellationTokenSource = new CancellationTokenSource();
var task = client.ExecuteTaskAsync(request, cancellationTokenSource.Token);
task.Wait();
var response = task.Result;
最後一行拒絕編譯,告訴我它不能做一個隱式轉換。所以,我想有明確的轉換:
IRestResponse<DataRequestResponse> response = task.Result as IRestResponse<DataRequestResponse>;
,編譯,運行,但隨後崩潰(拋出一個NullReferenceException,稱「未將對象引用設置到對象的實例」)。 (順便說一下,一旦我有這個工作,那麼cancellationTokenSource.Token
當然會從主線程傳入,我也將添加一些代碼來檢測何時發生中止:我會拋出一個異常。 )
我的備份計劃只是放棄正在運行的整個線程。原油,但現在實際上已經足夠好了。但是,如果可以的話,我寧願「正確地」這樣做。
更多信息:
同步Execute
呼叫是在這裏:https://github.com/restsharp/RestSharp/blob/master/RestSharp/RestClient.Sync.cs#L55在那裏結束調用Http.AsGet()
或Http.AsPost()
,然後在這裏結束了:https://github.com/restsharp/RestSharp/blob/master/RestSharp/Http.Sync.cs#L194
換句話說,在幕後RestSharp是使用HttpWebRequest.GetResponse。這有一個Abort
函數,但作爲一個同步功能(即不會返回,直到請求完成),這對我來說沒有多大用處!
感謝您的回答。上面的代碼是否需要在用'async'標記的函數中?這是我嘗試使用ExecuteTaskAsync函數時遇到的問題之一。 –
@DarrenCook雖然通常是一個好主意,可以將'async'從您的調用堆棧中調出,您不必這樣做。在上面的示例中,您會注意到沒有'await'語句,而是使用'response = task.Result;'阻塞等待。所以包含這個代碼的方法不應該被標記爲'async'。或者,你可以使它'異步任務 MyMethod(...){...返回等待任務; }'並且讓調用'MyMethod'的客戶端代碼進行等待(阻塞或使用'await')。 –
Alex