我有 .NET 應用程式,并且我的 GUI 上有 DataGridView 和 TextBox 區域。我想要做的是當用戶更改 TextBox 文本時,更新包含此文本的單元格的 DataGridView。但是這個搜索應該作為異步任務運行,因為如果不是,它會導致 GUI 凍結。每次當用戶更改 TextBox 文本時,如果另一個搜索任務正在運行,我的應用程式應該取消并再次重新運行它以根據新的搜索值進行搜索。這是我的代碼;
CancellationTokenSource cts = new CancellationTokenSource();
private async void TextBox1_Changed(object sender, EventArgs e)
{
cts.Cancel();
CancellationToken ct = cts.Token;
try
{
await Task.Run(() =>
{
System.Diagnostics.Debug.WriteLine("Task started");
// Searching here.
System.Diagnostics.Debug.WriteLine("Task finished");
}, cts.Token);
}
catch
{
System.Diagnostics.Debug.WriteLine("Cancelled");
}
}
在我的代碼中,任務在沒有啟動的情況下被取消。我只在除錯控制臺上看到“已取消”行。我應該取消任務,因為如果我不這樣做,他們的數量和應用程式的 CPU 使用率就會增加。有沒有辦法做到這一點?
uj5u.com熱心網友回復:
就像 Rand Random 所說,我應該清除new CancellationTokenSource物件。我已經像這樣編輯了我的代碼并且它有效。代碼應該是這樣的:
CancellationTokenSource cts = new CancellationTokenSource();
private async void TextBox1_Changed(object sender, EventArgs e)
{
cts.Cancel();
cts.Dispose();
cts = new CancellationTokenSource();
try
{
await Task.Run(() =>
{
System.Diagnostics.Debug.WriteLine("Task started");
// Searching here.
System.Diagnostics.Debug.WriteLine("Task finished");
}, cts.Token);
}
catch
{
System.Diagnostics.Debug.WriteLine("Cancelled");
}
}
uj5u.com熱心網友回復:
如果您想讓自己的生活更輕松,您應該考慮使用 Microsoft 的 Reactive Framework(又名 Rx)
我假設您可以撰寫此方法:
async Task<string[]> DoSearchAsync(string text, CancellationToken ct)
{
/* you implement this method */
}
然后你可以這樣做:
private IDisposable _searchSubscription = null;
private void Form1_Load(object sender, EventArgs e)
{
_searchSubscription =
Observable
.FromEventPattern(h => TextBox1.TextChanged = h, h => TextBox1.TextChanged -= h)
.Throttle(TimeSpan.FromMilliseconds(400.0))
.Select(ep => TextBox1.Text)
.Select(text => Observable.FromAsync(ct => DoSearchAsync(text, ct)))
.Switch()
.ObserveOn(TextBox1)
.Subscribe(results => { /* update your UI */ });
}
現在TextChanged,它會監視您的事件,等待 400.0 毫秒以防您鍵入另一個字符-如果用戶仍在鍵入,則觸發大量搜索是沒有意義的-然后它會呼叫您的新DoSearchAsync方法。
然后它執行一個Switch有效地意味著取消任何飛行中的搜索并開始這個新的搜索。
最后,它編組回 UI 執行緒,然后為您提供搜索結果,以便您可以更新 UI。
它只為您處理所有呼叫、后臺執行緒呼叫、編組回 UI。
如果你想關閉它,只需呼叫_searchSubscription.Dispose().
NuGetSystem.Reactive.Windows.Forms并添加using System.Reactive.Linq;以獲取位。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/407401.html
標籤:
下一篇:鏡像通用樹-我的錯誤是什么?
