[英]Cancel Parallel.ForEach or use async await
I have this event: 我有这个事件:
private void TextBoxSearchText_TextChanged(object sender, TextChangedEventArgs e)
{
searchText();
}
and I want to cancel this parallel method and start a new one when textbox text changes and also want my textbox be responsive to my new text typing, which is lock until results come to listbox. 我想取消此并行方法,并在文本框文本更改时启动一个新方法,并且还希望我的文本框对我的新文本键入作出响应,该锁定将保持锁定,直到结果进入列表框为止。
List<TextList> oSelected;
private void searchText()
{
string strSearchText = TextBoxSearchText.Text;
oSelected = new List<TextList>();
Parallel.ForEach(oTextList, item =>
{
Match myMatch = Regex.Match(item.EnglishText.ToString(), "\\b" + strSearchText.ToString().ToLower() + @"\w*", RegexOptions.IgnoreCase);
if (!myMatch.Success)
{
return;
}
oSelected.Add(new TextList
{
Id = item.Id,
EnglishText = item.EnglishText
});
});
ListBoxAllTexts.ItemsSource = oSelected;
}
Is it possible to use async and awiat to accomplish the job? 是否可以使用async和awiat完成任务? Which one is better for searching a text in almost 1 million line of text? 在几乎一百万行的文本中搜索文本哪个更好? I read alot about async and await but I couldn't understand how to use it in my work. 我阅读了很多有关异步的信息,然后等待,但是我不明白如何在工作中使用它。 Thank you 谢谢
Since your work is CPU-bound, you should use parallel code to do the actual search. 由于您的工作受CPU限制,因此应使用并行代码进行实际搜索。 However, you can wrap the parallel work in an async
/ await
mindset by using Task.Run
: 但是,您可以使用Task.Run
将并行工作包装在async
/ await
心态中:
private async void TextBoxSearchText_TextChanged(object sender, TextChangedEventArgs e)
{
ListBoxAllTexts.ItemsSource = await Task.Run(() => searchText(TextBoxSearchText.Text));
}
This will keep your UI responsive. 这将使您的UI保持响应。
To do cancellation, use a CancellationTokenSource
. 要取消,请使用CancellationTokenSource
。 On a side note, you can't update a List<T>
from a parallel loop like you're currently trying to do because List<T>
is not threadsafe. 附带说明一下,由于List<T>
不是线程安全的,因此无法像您当前尝试的那样从并行循环中更新List<T>
。 In this scenario, I recommend you use PLINQ instead: 在这种情况下,我建议您改用PLINQ:
private CancellationTokenSource _cts;
private async void TextBoxSearchText_TextChanged(object sender, TextChangedEventArgs e)
{
if (_cts != null)
_cts.Cancel();
_cts = new CancellationTokenSource();
var strSearchText = TextBoxSearchText.Text;
ListBoxAllTexts.ItemsSource = await Task.Run(
() => searchText(strSearchText, _cts.Token));
}
private List<TextList> searchText(string strSearchText, CancellationToken token)
{
try
{
return oTextList.AsParallel().WithCancellation(token)
.Where(item => Regex.IsMatch(item.EnglishText.ToString(), "\\b" + strSearchText.ToLower() + @"\w*", RegexOptions.IgnoreCase))
.Select(item => new TextList
{
Id = item.Id,
EnglishText = item.EnglishText
})
.ToList();
}
catch (OperationCanceledException)
{
return null;
}
}
Also, consider throttling the user input by only starting the search after a delay. 另外,请考虑仅在延迟后才开始搜索来限制用户输入。 Rx is the best way to do that. Rx是执行此操作的最佳方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.