C# 如何在LINQ查询中取消异步操作?
这个问题延续了我以前的问题。假设我有一个LINQ,比如我们:C# 如何在LINQ查询中取消异步操作?,c#,wpf,linq,task,C#,Wpf,Linq,Task,这个问题延续了我以前的问题。假设我有一个LINQ,比如我们: var query = from var item in items where item.X == 1 select item; 我可以异步迭代整个查询,并将每个项目分派到UI(或者我可以使用IProgress): 现在我想取消查询。。。我可以简单地声明一个cancelActionTokenSourcects,将一个令牌放入任务中,然后: foreach(var item in query) { cts.Token.Thr
var query = from var item in items where item.X == 1 select item;
我可以异步迭代整个查询
,并将每个项目分派到UI(或者我可以使用IProgress
):
现在我想取消查询。。。我可以简单地声明一个cancelActionTokenSource
cts,将一个令牌放入任务中,然后:
foreach(var item in query)
{
cts.Token.ThrowIfCancellationRequested();
Application.Current.Dispatcher.BeginInvoke(
new Action(() => source.Add(item)));
}
问题是,我只能在新结果出现时取消。因此,如果有一长串的项目不符合我的查询条件,我的取消请求将被忽略
如何将取消包含到LINQ(到对象)中,并能够检查每个项目的取消令牌?我不确定,因为我没有测试它。。。但我认为您可以将其作为linq查询中的副作用,也可以在where中创建一个方法,例如: 更改此项:
var query = from var item in items where item.X == 1 select item;
致:
并创建一个方法:
private bool CancelIfRequestedPredicate<T>(T item,Predicate<T> predicate)
{
cts.Token.ThrowIfCancellationRequested();
return predicate(item);
}
private bool CancelIfRequestedPredicate(T项,谓词谓词)
{
cts.Token.ThrowIfCancellationRequested();
返回谓词(项);
}
由于linq使用延迟执行,我认为它将在每次迭代中运行您的方法
作为观察,我不知道如果不使用linqtoobjects会发生什么行为(您没有提到是否使用linqtosql或类似的东西)。但这可能行不通
希望对您有所帮助。有关此问题的特定于实体的框架版本: 今天,我已经四处搜寻了一段时间,试图找到这个问题的答案,但最终我发现了一个明确的答案(我访问过的30多页中的一页) 这是一个针对实体框架运行的linq查询 对于实体框架的更高版本(截至目前) ToListSync有一些扩展方法,其中包括接受取消令牌的重载 正如task(在我的例子中,我的查询是在task中)一样,我在中运行了查询,但这是我最关心的数据查询
var sourceToken = new System.Threading.CancellationTokenSource();
var t2 = System.Threading.Tasks.Task.Run(() =>
{
var token = sourceToken.Token;
return context.myTable.Where(s => s.Price == "Right").Select(i => i.ItemName).ToListAsync(token);
}
, sourceToken.Token
);
private bool CancelIfRequestedPredicate<T>(T item,Predicate<T> predicate)
{
cts.Token.ThrowIfCancellationRequested();
return predicate(item);
}
var sourceToken = new System.Threading.CancellationTokenSource();
var t2 = System.Threading.Tasks.Task.Run(() =>
{
var token = sourceToken.Token;
return context.myTable.Where(s => s.Price == "Right").Select(i => i.ItemName).ToListAsync(token);
}
, sourceToken.Token
);