none
simple async RRS feed

  • General discussion

  • i want to invoke a long process, which it will update many ui elements (TextBlock, DataGrid, etc).

    i already have this process done, and working fine in normal approach. as the process can be long depend on input data, progressing data at times are refresh at some ui elements (TextBlock, DataGrid, etc).

    now i want to write a simple async invoking this method, so during long process, use can interace with the ui as normal, instead now the process is being holding up.

    i tried few aynch codings as below, but they just worked as sync mode.

            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                // try 1:
                Task.Run(() => { MyProcess(data); });
                
                // try #2:
                Action task = () =>
                {
                    MyProcess(data);
                };
                Dispatcher.BeginInvoke(task);
            }
    
    what am i missing?

    • Changed type Kelmen Thursday, April 26, 2018 9:47 AM no practical resolution
    Wednesday, April 25, 2018 4:39 PM

All replies

  • Hi Kelmen,

    Please try the following code.

    private async void Window_Loaded(object sender, RoutedEventArgs e)
            {
               var task = Task.Run(() => RunLongTask("Test1"));
                t1.Text = await task;
            }
    
            private static string RunLongTask(string taskName)
            {
                Thread.Sleep(5000);
                return taskName + "Completed!";
            }

    If you want to use MVVM pattern. please refer to the following article about Async Programming : Patterns for Asynchronous MVVM Applications: Data Binding

    https://msdn.microsoft.com/en-us/magazine/dn605875.aspx

    Best regards,

    Zhanglong


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, April 26, 2018 3:21 AM
    Moderator
  • Hi Kelmen,

    Please try the following code.

    ...
            private static string RunLongTask(string taskName)
            {
                Thread.Sleep(5000);
                return taskName + "Completed!";
            }
    ...

    Hi Zhanglong,

    My method process involved interacting with UI elements on the Window control, can't use static.

    trying to adopt ur sample :

            private async void Window_Loaded(object sender, RoutedEventArgs e)
            {
                
                var task = Task.Run(() => Process2(data) );
                var xx = await task;
            }
    
            async Task<string> Process2(data)
            {
                Process(data);
                return null;
            }
    

    but getting error "The calling thread cannot access this object because a different thread owns it."

    Thursday, April 26, 2018 8:25 AM
  • I'm not 100% sure but I dont think the new task can access the GUI interface directly. You have to use wait in the main thread and then make the main thread show the result.

    Look at the GUI as your customer and all the tasks as people working for you. This system makes your people first give your done work back to you, and then you give it back to the customer.

    • Edited by ThisNewbie Thursday, April 26, 2018 9:02 AM
    Thursday, April 26, 2018 8:55 AM
  • after few more googling, i believe there is no ***simple*** async coding when the process involved ui elements.

    i came across simple code to update ui on main thread:

    https://stackoverflow.com/questions/24482818/solving-the-calling-thread-cannot-access-this-object-because-a-different-thread

                string progressMsg1 = string.Format(...), 
                Dispatcher.BeginInvoke(new Action<string>(ShowProgress), System.Windows.Threading.DispatcherPriority.Normal, progressMsg1);
    
    ...
            void ShowProgress(string txt)
            {
    uiTextBlock.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Input, CustomUtils.EmptyDelegate);
            }
    

    which can help resolve error "The calling thread cannot access this object because a different thread owns it." i encountered.

    however, i'm hindering by more issues related UI threading constraint/error, as the process need to generate image dynamically involving Canvas etc.

    this just hinting me ***major*** code changes impact.

    i'm dropping this ***simple*** async as it's just an optional feature. 

    Thursday, April 26, 2018 9:46 AM