简体   繁体   English

如何从异步任务有效地更新WPF MainWindow

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM