gpt4 book ai didi

.net - 如何取消任何当前的 Parallel.ForEach 并重新开始

转载 作者:行者123 更新时间:2023-12-04 19:14:34 24 4
gpt4 key购买 nike

从功能上讲,有一长串单词绑定(bind)到 ListView。使用 TextBox for chars 过滤单词列表。

使用任何新的 char 需要取消任何处理背景过滤器。然后等待 1 秒 (DispatcherTimer) 以启动新的后台并行过滤器。

使用 BackGroundWorker 进行此工作,但无法将 cancel-any-processing 部分转换为 Parallel。
基本上需要“if (backgroundWorkerFTSfilter.IsBusy) backgroundWorkerFTSfilter.CancelAsync();”在平行下。
如果我要解决这个错误,请告诉我。

private List<FTSword> fTSwordsFiltered = new List<FTSword>();
CancellationTokenSource ftsCts = new CancellationTokenSource();
ParallelOptions ftspo = new ParallelOptions();
// in ctor ftspo.CancellationToken = ftsCts.Token;

public List<FTSword> FTSwordsFiltered // ListView bound to
{
get { return fTSwordsFiltered; }
set
{
if (fTSwordsFiltered == value) return;
fTSwordsFiltered = value;
NotifyPropertyChanged("FTSwordsFiltered");
}
}
public string FTSwordFilter // TextBox bound to
{
get { return fTSwordFilter; }
set
{
if (value == fTSwordFilter) return;

fTSwordFilter = value;
NotifyPropertyChanged("FTSwordFilter");

// cancel any filter currently processing
ftsCts.Cancel(); // fts filter
// with BackgroundWorker this was able to cancel
// if (backgroundWorkerFTSfilter.IsBusy) backgroundWorkerFTSfilter.CancelAsync();

dispatcherTimerFTSfilter.Stop();
// wait 1 second and apply filter in background
dispatcherTimerFTSfilter.Start();
}
}
private void dispatcherTimerFTSfilter_Tick(object sender, EventArgs e)
{
dispatcherTimerFTSfilter.Stop();
List<FTSword> ftsWords = new List<FTSword>();
//ftsCts = new CancellationTokenSource(); with these two it never cancels
//ftspo.CancellationToken = ftsCts.Token;
if (!(string.IsNullOrEmpty(FTSwordFilter)))
{
Task.Factory.StartNew(() =>
{

try
{
Parallel.ForEach(FTSwords, ftspo, ftsw =>
{
if (ftsw.WordStem.StartsWith(FTSwordFilter))
{
ftsWords.Add(ftsw);
}
ftspo.CancellationToken.ThrowIfCancellationRequested();
});
Thread.Sleep(1000); // so the next key stoke has time
FTSwordsFiltered = (List<FTSword>)ftsWords;
}
catch (OperationCanceledException ei)
{
// problem is that it is always cancelled from the cancel request before DispatchTimer
Debug.WriteLine(ei.Message);
}
Debug.WriteLine(ftsWords.Count.ToString() + "parallel ");
});
}
}

Irman 的回答使我想到了这一点
    if (!(string.IsNullOrEmpty(FTSwordFilter)))
{
string startWorkFilter = FTSwordFilter;
Task.Factory.StartNew(() =>
{
try
{
fTSwordsFilteredCancel = false;
Parallel.ForEach(FTSwords, ftspo, (ftsw, loopstate) =>
{
if (ftsw.WordStem.StartsWith(startWorkFilter))
{
ftsWords.Add(ftsw);
}
// Thread.Sleep(1);
if (fTSwordsFilteredCancel)
{
loopstate.Break();
}
});
Debug.WriteLine("fTSwordsFilteredCancel " + fTSwordsFilteredCancel.ToString());
FTSwordsFiltered = (List<FTSword>)ftsWords;
Debug.WriteLine(ftsWords.Count.ToString() + " parallel " + startWorkFilter);
}
catch (OperationCanceledException ei)
{
Debug.WriteLine(ei.Message);
}
});
}

非常感谢我的回答,并将将其用于一些运行时间更长的任务或更长的列表,但获得了如此出色的性能,我将其移至 get(仍然有 1 秒的延迟)。导致更小的内存占用。针对 800,000,它的运行时间不到 1/10 秒。
public IEnumerable<FTSword> FTSwordsFiltered
{
get
{
if(string.IsNullOrEmpty(FTSwordFilter) || FTSwordFilter == "*") return FTSwords;
return FTSwords.AsParallel().Where(ftsWrd => ftsWrd.WordStem.StartsWith(FTSwordFilter));
}

最佳答案

Parallel.ForEach 带有 ParallelLoopState 对象。你可以使用这个对象来打破循环。

您可以使用 loopState.Break()loopState.Stop()根据您的要求。

检查这个。

http://msdn.microsoft.com/en-us/library/dd991486.aspx

关于.net - 如何取消任何当前的 Parallel.ForEach 并重新开始,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11300012/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com