我在用户界面上有一个组合框,在选择更改时,它会异步地去访问网络服务,以获取一些要在用户界面上显示的信息(使用新的 C#5 async/await 关键字)。我想要做的是在发送新请求之前取消当前的异步请求;例如,如果用户使用键盘快速循环浏览所有组合框项目,则 SelectionChanged 事件可能会在第一个异步请求返回之前触发多次(生成多个异步请求)。
所以我的异步函数被从组合框的 SelectionChanged 事件调用,代码如下:
public async Task<Connections> ConnectionsAsync()
{
return await Task.Factory.StartNew(() => Connections, _cancellationTokenSource.Token);
}
Connections是一个属性,用于连接Web服务。因此,由于CancellationTokenSource一旦被取消就无法重复使用,我计划采取以下措施:
public async Task<Connections> ConnectionsAsync()
{
_cancellationTokenSource.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
return await Task.Factory.StartNew(() => Connections, _cancellationTokenSource.Token);
}
问题在于,有时候我会在没有异步命令运行的情况下调用Cancel()(例如第一次调用此函数);因此,如果我挂接了任何取消事件处理程序,它们将被调用,甚至在我发出异步请求之前。
是否有办法检查异步请求是否已经在运行?除了我做类似以下操作的方式:
public async Task<Connections> ConnectionsAsync()
{
if (_runningAsyncCommand)
_cancellationTokenSource.Cancel();
_cancellationTokenSource = new CancellationTokenSource();
_runningAsyncCommand = true;
return await Task.Factory.StartNew(() => Connections, _cancellationTokenSource.Token);
_runningAsyncCommand = false;
}
我有一些异步函数,它们都使用相同的CancellationTokenSource,所以我必须在所有这些函数中实现这个“管道”。这是最好的方法吗?还是有更好的方法?
另外,如果我公开_cancellationTokenSource,以便其他类可以向其注册取消委托,那么将这些委托“转移”到新的CancellationTokenSource的最佳方法是什么,因为我每次都创建一个新的?
提前感谢!