更新GUI的后台进程

时间:2017-06-01 06:34:47

标签: c# wpf user-interface async-await

我正在创建一个从数据库中读取表并将它们转储到文件中的应用程序。用户要求转储一个文件,然后作为第二个任务,然后是第三个任务。我希望在任务结束时或者如果它们失败时在GUI上显示。我很难在我的任务和GUI之间进行通信。这是我的gui的代码:

namespace ClientCsvDumper
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
async void go_Click(object sender, RoutedEventArgs e)
        {
            String database_name;
            String schema_name;
            String output_file_name;

            database_name = this.database_name.SelectedItem.ToString();

            output_file_name = this.output_file_name.Text;

            SqlConnection conn = new SqlConnection("Data Source="+this.server_name.Text+";Initial Catalog="+"MASTER"+";Integrated Security=True");
            if (this.query_button.IsChecked.Value) {
                String query_text;
                query_text = this.query_textbox.Text;
                thread_number++;
                await Task.Run(() => {
                    UpdateWindows("task " + thread_number.ToString() + " started");
                    AsyncDumpQueryToFile(conn, database_name, query_text, output_file_name);
                });


            }
            else {
                schema_name = this.schema_name.SelectedItem.ToString();
                String table_name;
                table_name = this.table_name.SelectedItem.ToString();
                thread_number++;
                await Task.Run(() => {UpdateWindows("task " + thread_number.ToString() + " started");
                    AsyncDumpTableToFile(conn, database_name, schema_name, table_name, output_file_name);
                });

             }

        }

async Task AsyncDumpTableToFile( SqlConnection connection, string database_name, string schema_name, string tableName, string destinationFile) {
           // gui.UpdateWindows("Work Started");
            TableDumper ts = new TableDumper();
            ts.DumpTableToFile(connection, database_name, schema_name, tableName, destinationFile);

          //  gui.UpdateWindows("Done");
        }
        async Task AsyncDumpQueryToFile( SqlConnection connection, string database_name, string query, string destinationFile)
        {
            //gui.UpdateWindows("Work Started");
            TableDumper ts = new TableDumper();
            ts.DumpQueryToFile( connection,  database_name,  query,  destinationFile);

           // gui.UpdateWindows("Done");
        }

        void UpdateWindows(String text) {

            Dispatcher.Invoke(() => { status.Text += text; });
        }

首先,我尝试(使用来自网络的代码)将gui 0bject传递给函数AsyncDumpTableToFile(所以我可以修改gui上的东西,但它崩溃说主线程使用并拥有它。

如何在主GUI上打印有关runnin任务的信息(已启动,正在运行,失败(异常消息),SUccess)?

还有什么好的阅读让我更了解这种东西吗?

一切顺利

文森特

1 个答案:

答案 0 :(得分:1)

我同意Peter的理解,你的理想解决方案将使用MVVM。但是,您也可以使用基于IProgress<T>的现代方法直接访问UI元素,例如:

async void go_Click(object sender, RoutedEventArgs e)
{
  IProgress<string> progress = new Progress<string>(text => status.Text += text);
  ...
  await Task.Run(() =>
  {
    progress.Report("task " + thread_number.ToString() + " started");
    AsyncDump*ToFile(..., progress);
  });
  ...
}

async Task AsyncDump*ToFile(..., IProgress<string> progress)
{
  progress.Report("Work Started");
  ...
  progress.Report("Done");
}

此模式的重要部分是在UI线程上必须创建Progress<T>对象。然后它将为您处理线程编组。