[英]Dynamically search with interrupts,via Tasks C#
我正在使用Db(通過SQLite.NET PCL ,而不是異步版本)。 在目前我有一個列表視圖與一些數據(取自數據庫),我也有一個搜索欄/條目(其nvm),用戶可以輸入一些值然后,通過LINQ我將進行查詢和更新SourceItems我的清單。
所以問題來自於性能,因為我的數據庫有百萬條記錄和簡單的LINQ查詢工作非常慢。換句話說,當用戶輸入的數據太快時,應用程序會有很大的滯后,有時會崩潰 。
為了解決這個問題,我想到了一些事情(理論上的解決方案):
1)需要在任務上放置方法(我對db進行查詢)(解鎖我的主UI線程)
2)初始化計時器,然后打開並:
類似的東西(類似)或任何建議。謝謝!
UPD:
所以說實話,我嘗試了太多,並沒有得到一個好結果
BTW ,我目前的代碼(Snippets):
1)我的SearchMethod
public void QueryToDB(string filter)
{
this.BeginRefresh ();
if (string.IsNullOrWhiteSpace (filter))
{
this.ItemsSource = SourceData.Select(x => x.name); // Source data is my default List of items
}
else
{
var t = App.DB_Instance.FilterWords<Words>(filter); //FilterWords it's a method,where i make direct requests to the database
this.ItemsSource = t.Select(x => x.name);
}
this.EndRefresh ();
}
2)Searchbar.TextChanged(匿名方法)
searchBar.TextChanged +=async (sender, e) =>
{
ViewModel.isBusy = true; //also i got a indicator,to show progress,while query working
await Task.Run(()=> //my background,works fine
{
listview.QueryToDB(searchBar.Text);
});
ViewModel.isBusy = false; // after method is finished,indicator turn off
};
主要的問題是如何實現這個部分(使用這些情況),其中1秒傳遞,然后我將進行查詢以更新我的listItems列表(每次,當用戶輸入一些值到搜索欄,這個觸發器(計時器) )必須再次刷新為零)。
任何幫助將不勝感激,謝謝!
PS對不起我的工程師。 技能!
一種方法是組合async Task.Run
和CancellationTokenSource
:
CancellationTokenSource cancellationTokenSource;
searchView.TextChanged += async (sender, e) =>
{
if (cancellationTokenSource != null) cancellationTokenSource.Cancel();
cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
var searchBar = (sender as SearchBar);
if (searchBar != null)
{
string searchText = searchBar.Text;
try
{
await Task.Delay(650, cancellationToken);
if (cancellationToken.IsCancellationRequested) return;
var searchResults = await Task.Run(() =>
{
return ViewModel.Search(searchText);
});
if (cancellationToken.IsCancellationRequested) return;
ViewModel.YouItems.Repopulate(searchResults);
}
catch (OperationCanceledException)
{
// Expected
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
};
您想在實際執行搜索之前等待 。 在中途殺死搜索任務可能會導致未定義的行為。
您想要保存當前搜索過濾器,並在1秒后再次對其進行比較。 如果沒有改變,請進行搜索。 否則,中止:
searchBar.TextChanged += async (sender, e) =>
{
var filter = searchBar.Text;
await Task.Run(() =>
{
Thread.Sleep(1000);
if (filter == searchBar.Text)
listview.QueryToDB(searchBar.Text);
});
};
以保持視圖模型更新,將您isBusy
分配內部QueryToDB
,因為這是當你的視圖模型是真正的忙:
public void QueryToDB(string filter)
{
this.BeginRefresh ();
ViewModel.isBusy = true;
// do your search
ViewModel.isBusy = false;
this.EndRefresh ();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.