我们有一棵树,当用户点击任何节点时,它将从Web服务查询数据,并替换结果。但是,有时需要时间。所以我尝试将 Web 服务调用包装在任务中。我想在任务未完成时取消任务,用户单击其他节点。以下是我的示例代码。但是,取消任务块无法执行,即使 _cancelTokenSource.Cancel() 也无法执行。MSDN 提供的大多数示例都基于 CPU 绑定,而不是 I/O 绑定。谁能告诉我如何取消所有网络服务?提前致谢
private void OnNodeClicked(int id)
{
if (_cancelTokenSource != null)
_cancelTokenSource.Cancel();
IsRunning = true;
var uiSchedule = System.Threading.Tasks.TaskScheduler.FromCurrentSynchronizationContext();
_cancelTokenSource = new CancellationTokenSource();
var loadDataTask = System.Threading.Tasks.Task.Factory.StartNew<int[]>(() =>
{
// Call web service here
}, _cancelTokenSource.Token);
loadDataTask.ContinueWith((result) =>
{
// Populate data
IsRunning = false;
}, CancellationToken.None, System.Threading.Tasks.TaskContinuationOptions.OnlyOnRanToCompletion, uiSchedule);
loadDataTask.ContinueWith((result) =>
{
// set cancel state here
IsRunning = false;
}, CancellationToken.None, System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled, uiSchedule);
}
CancellationTokenSource
及其令牌是一个线程(或任务)查询另一个线程是否重新质疑任务取消的一种方式。 当然,这需要您编写检查该令牌的代码(因此至少运行一次,并且通常定期运行一次)。 如果已委派给某些生成的代码(Web 服务代理),而这些代码对任务或取消令牌一无所知,则无法使用它。
如果使用 Begin 方法启动调用,则可以使用 WebClientAsyncResult.Abort()
中止调用。 例如:
IAsyncResult ar = obj.BeginFunCall(5,5,null,null);
//...
if (!ar.IsCompleted) //if the request is not completed {
WebClientAsyncResult wcar = (WebClientAsyncResult)ar;
wcar.Abort();//abort the call to web service
}