[英]How to efficently update WPF MainWindow from an async task
Is this an acceptable approach to update WPF MainWindow from an async task
, using events thrown from a public static class
? 这是使用从public static class
引发的事件从async task
更新WPF MainWindow的可接受方法吗?
In MainWindow.cs, I subscribe to UI.TaskCompleted
event In UI.cs, I subscribe to AsyncTaskActions.TaskCompleted
event. 在MainWindow.cs中,我订阅UI.TaskCompleted
事件。在UI.cs中,我订阅AsyncTaskActions.TaskCompleted
事件。
Using this pattern, AsyncTaskActions.TaskCompleted
is raised with a async task is completed. 使用此模式,将在完成异步任务后引发AsyncTaskActions.TaskCompleted
。 UI catch the event and raise UI.TaskCompleted
. UI捕获事件并引发UI.TaskCompleted
。 This way, the event is catch in MainWindow code where I can use Displacher.Invoke
to refresh the displayed page. 这样,在MainWindow代码中捕获了事件,在这里我可以使用Displacher.Invoke
刷新显示的页面。 The end result is I get a page refresh when a task is completed and the task still runs asynchronously
. 最终结果是,当任务完成并且任务仍asynchronously
运行时,我将刷新页面。
Application design summary: 应用程序设计摘要:
MainWindow: main window which can have several different page classes in content area within the main window. MainWindow:主窗口,在主窗口的内容区域中可以具有几个不同的页面类。
Common.cs public static class contains a number of common methods through the UI in the application. Common.cs公共静态类通过应用程序中的UI包含许多常用方法。
AsyncTaskActions.cs - class with a number of
async
common methods (ie download file) AsyncTaskActions.cs-具有许多async
常用方法的类(即下载文件)
Code snippets: 代码段:
public partial class MainWindow
public MainWindow()
{
UI.TaskCompleted += UI_TaskCompleted;
}
void UI_TaskCompleted(EventArgs e)
{
Dispatcher.Invoke(new Action(this.PageRefresh));
}
public void PageRefresh()
{
var page = ((ContentArea)).Content;
if (page == null) return;
switch (page.GetType().Name)
{
case "SearchPage":
((SearchPage) page).SearchParts();
break;
case "LegoPartPage":
((LegoPartPage) page).LoadData();
break;
case "LegoSetPage":
((LegoSetPage) page).LoadData();
break;
case "MainPage":
((MainPage) page).LoadData();
break;
case "MiniFigPage":
((MiniFigPage) page).LoadData();
break;
}
}
}
public static class UI
{
public delegate void TaskComplete(EventArgs e);
public static event TaskComplete TaskCompleted;
public static async Task<int> DownloadPriceSummaryAsync(String itemNo, Int64 colorId)
{
var wAsyncTaskClasses = new AsyncTaskClasses();
wAsyncTaskClasses.TaskCompleted += wAsyncTaskClasses_TaskCompleted;
Task<HtmlDocument> task = wAsyncTaskClasses.DownloadPriceGuide(string.Format(Common.BrickLinkPrice, itemNo, colorId), itemNo, colorId);
return await wAsyncTaskClasses.ParsePriceSummaryAsync(task, itemNo, colorId);
}
}
public class AsyncTaskActions
{
public delegate void TaskComplete(object sender, EventArgs e);
public event TaskComplete TaskCompleted;
public async Task<int> ParsePriceSummaryAsync(Task<HtmlDocument> task, string itemNo, Int64 colorId)
{
return await Task.Run(() => ParsePriceSummary(task, itemNo, colorId));
}
public int ParsePriceSummary(Task<HtmlDocument> task, string itemNo, Int64 colorId)
{
... some code....
if (null != TaskCompleted)
{
TaskCompleted(this, new EventArgs());
}
return recordCount;
}
You are marshaling all events to the UI context with Dispatcher.BeginInvoke
and that appears safe. 您正在使用Dispatcher.BeginInvoke
将所有事件编组到UI上下文中,这看起来很安全。
As usual, if it works, it works! 和往常一样, 如果有效,就可以!
As an aside - there is not much about this design that I would personally consider acceptable. 顺便说一句-我个人认为这种设计没有太多可以接受的。 Is it reasonable to assume you are from an procedural or functional background? 假设您来自程序或功能背景是否合理? It might help to throw this at Code Review for more information and some OO tips. 将其扔给Code Review以获得更多信息和一些OO技巧可能会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.