[英]Cancel Parallel.ForEach or use async await
我有這個事件:
private void TextBoxSearchText_TextChanged(object sender, TextChangedEventArgs e)
{
searchText();
}
我想取消此並行方法,並在文本框文本更改時啟動一個新方法,並且還希望我的文本框對我的新文本鍵入作出響應,該鎖定將保持鎖定,直到結果進入列表框為止。
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;
}
是否可以使用async和awiat完成任務? 在幾乎一百萬行的文本中搜索文本哪個更好? 我閱讀了很多有關異步的信息,然后等待,但是我不明白如何在工作中使用它。 謝謝
由於您的工作受CPU限制,因此應使用並行代碼進行實際搜索。 但是,您可以使用Task.Run
將並行工作包裝在async
/ await
心態中:
private async void TextBoxSearchText_TextChanged(object sender, TextChangedEventArgs e)
{
ListBoxAllTexts.ItemsSource = await Task.Run(() => searchText(TextBoxSearchText.Text));
}
這將使您的UI保持響應。
要取消,請使用CancellationTokenSource
。 附帶說明一下,由於List<T>
不是線程安全的,因此無法像您當前嘗試的那樣從並行循環中更新List<T>
。 在這種情況下,我建議您改用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;
}
}
另外,請考慮僅在延遲后才開始搜索來限制用戶輸入。 Rx是執行此操作的最佳方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.