我有一个关于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,()=> {});' 我也尝试过使用'调度员“,但结果相似。 –