我有这条线,它不阻塞(同步)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