WPF/C# Don't block the UI

后端 未结 6 1221
再見小時候
再見小時候 2020-12-20 03:11

I\'ve an existing WPF application, which has several sections. Every section is a UserControl, that implements an interface.

The interface specify two methods:

6条回答
  •  余生分开走
    2020-12-20 04:04

    Treat UnloadData as a async operation and let the async/await features handle both the case when it completes synchronously and when it needs to complete asynchronously:

    public async Task UnloadData(){
        if(...){
            // The await keyword will segment your method execution and post the continuation in the UI thread
            // The Task.Factory.StartNew will run the time consuming method in the ThreadPool
            await Task.Factory.StartNew(()=>LaunchMyTimeConsumingMethodWithBackgroundWorker());
            // The return statement is the continuation and will run in the UI thread after the consuming method is executed
            return true;
        }
        // If it came down this path, the execution is synchronous and is completely run in the UI thread       
        return false;
    }
    
    
    private async void button_Click(object sender, RoutedEventArgs e)
    {
            // Put here your logic to prevent user interaction during the operation's execution.
            // Ex: this.mainPanel.IsEnabled = false;
            // Or: this.modalPanel.Visibility = Visible;
            // etc
    
            try
            {
                bool result = await this.UnloadData();
                // Do whatever with the result
            }
            finally
            {
                // Reenable the user interaction
                // Ex: this.mainPanel.IsEnabled = true;
            }
    }
    

    EDIT

    If you can't modify the UnloadData, then just execute it on the ThreadPool, as @BTownTKD noted:

        private async void button_Click(object sender, RoutedEventArgs e)
    {
            // Put here your logic to prevent user interaction during the operation's execution.
            // Ex: this.mainPanel.IsEnabled = false;
            // Or: this.modalPanel.Visibility = Visible;
            // etc
    
            try
            {
    
                // The await keyword will segment your method execution and post the continuation in the UI thread
                // The Task.Factory.StartNew will run the time consuming method in the ThreadPool, whether it takes the long or the short path
                bool result = await The Task.Factory.StartNew(()=>this.UnloadData());
                // Do whatever with the result
            }
            finally
            {
                // Reenable the user interaction
                // Ex: this.mainPanel.IsEnabled = true;
            }
    }
    

提交回复
热议问题