Code Review Stack Exchange is a question and answer site for peer programmer code reviews. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Is this an acceptable approach to update WPF MainWindow from an async task, using events thrown from a public static class?

  • In MainWindow.cs, I subscribe to UI.TaskCompleted event
  • In UI.cs, I subscribe to AsyncTaskActions.TaskCompleted event

Using this pattern, AsyncTaskActions.TaskCompleted is raised when an async task is completed. UI catch the event and raise UI.TaskCompleted. This way, the event is caught in MainWindow where I can use Displacher.Invoke to refresh the displayed page. The end result is I get a page refresh when a task is completed and the task still runs asychronously.

Application design summary:

  • MainWindow: main window which can have several different page classes in content area within the main window.
  • Common.cs public static class contains a number of common methods through the UI in the application.
  • AsyncTaskActions.cs - class with a number of async common methods (i.e. download file)

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;

            //if (page.GetType().Name == "")
            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)
    {


        if (null != TaskCompleted)
        {
            TaskCompleted(this, new EventArgs());
        }

        return recordCount;
    }
share|improve this question
    
Cross-posted to Stack Overflow: C# How to efficently update WPF MainWindow from an async task – rolfl Oct 26 '15 at 13:05
1  
I would not suggest leaving this in your code in the question ... some code..... Either provide the code or just remove this line, it makes your code look incomplete. – Marc-Andre Oct 26 '15 at 14:01

I would look into MVVM, then your async task will operate on the ViewModel and not the UI element. Then WPF will update the UI when it deem fit.

I like Caliburn.Micro for the MVVM parts

https://github.com/Caliburn-Micro

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.