我有一個關於UI的問題並從任務更新它。 試圖將我的應用程序從winforms移植到UWP,並且在此過程中,我想優化應用程序的CPU大部分。C#從並行運行的多個任務更新UI
以前我用背景工作來運行計算,但是使用Task API,我可以提高很多速度。嘗試更新UI時出現問題。
我正在掃描DNA鏈中的一些「特徵」,我有。
當掃描開始時,我想用當前的'任務'在UI上更新標籤。
掃描完成後,我想發送該功能的「大小」,以便可以使用掃描的數據量更新UI(進度條和標籤)。
如果找到了該功能,我想將它發送到UI以便在列表視圖中顯示。
我目前的代碼在某種程度上起作用。它掃描DNA並找到功能並更新UI。但是,UI凍結了很多,有時它在整個過程中不會更新幾次。
爲了解決我的問題,我已經在網上搜索了幾天,但我無法弄清楚最好的方法,或者我應該簡單地刪除任務並返回單個背景工作。
所以我的問題是這個問題的正確方法是什麼。
如何設置我的任務並同時以可靠的方式從多個任務報告回UI線程?
我寫了類似於我目前的設置是什麼代碼示例:
public class Analyzer
{
public event EventHandler<string> ReportCurrent;
public event EventHandler<double> ReportProgress;
public event EventHandler<object> ReportObject;
private List<int> QueryList; //List of things that need analysis
public Analyzer()
{
}
public void Start()
{
Scan();
}
private async void Scan()
{
List<Task> tasks = new List<Task>();
foreach (int query in QueryList)
{
tasks.Add(Task.Run(() => ScanTask(query)));
}
await Task.WhenAll(tasks);
}
private void ScanTask(int query)
{
ReportCurrent?.Invoke(null, "name of item being scanned");
bool matchfound = false;
//Do work proportional with the square of 'query'. Values range from
//single digit to a few thousand
//If run on a single thread completion time is around 10 second on
//an i5 processor
if (matchfound)
{
ReportObject?.Invoke(null, query);
}
ReportProgress?.Invoke(null, query);
}
}
public sealed partial class dna_analyze_page : Page
{
Analyzer analyzer;
private void button_click(object sender, RoutedEventArgs e)
{
analyzer = new Analyzer();
analyzer.ReportProgress += new EventHandler<double>(OnUpdateProgress);
analyzer.ReportCurrent += new EventHandler<string>(OnUpdateCurrent);
analyzer.ReportObject += new EventHandler<object>(OnUpdateObject);
analyzer.Start();
}
private async void OnUpdateProgress(object sender, double d)
{
//update value of UI element progressbar and a textblock ('label')
//Commenting out all the content the eventhandlers solves the UI
//freezing problem
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => { /*actual code here*/});
}
private async void OnUpdateCurrent(object sender, string s)
{
//update value of UI element textblock.text = s
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => { });
}
private async void OnUpdateObject(object sender, object o)
{
//Add object to a list list that is bound to a listview
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,() => { });
}
}
我希望我的問題是清楚的。謝謝。
當前的解決方案,唯一的解決辦法我已經能夠找到到目前爲止 而是在同一時間推出281個的任務,我啓動4,等待他們的終點:
List<Task> tasks = new List<Task>();
for (int l = 0; l < QueryList.Count; l++)
{
Query query= QueryList[l];
tasks.Add(Task.Run(() => { ScanTask(query); }, taskToken));
//somenumber = number of tasks to run at the same time.
//I'm currently using a number proportional to the number of logical processors
if (l % somenumber == 0 || l == QueryList.Count + 1)
{
try
{
await Task.WhenAll(tasks);
}
catch (OperationCanceledException)
{
datamodel.Current = "Aborted";
endType = 1; //aborted
break;
}
catch
{
datamodel.Current = "Error";
endType = 2; //error
break;
}
}
}
它是'Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync'嗎? –
是: 'await Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,()=> {});' 我也嘗試過使用'調度員「,但結果相似。 –