Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在LINQ查询中取消异步操作?_C#_Wpf_Linq_Task - Fatal编程技术网

C# 如何在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

这个问题延续了我以前的问题。假设我有一个LINQ,比如我们:

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
);