2017-06-01 66 views
0

我正在创建一个应用程序从数据库中读取表并将它们转储到文件中。用户要求转储一个文件,之后作为第二个任务,然后是第三个,然后是第三个。我期望在任务芬兰语或者它们失败时在GUI上显示。我很难在我的任务和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; }); 
     } 

开始我尝试(使用代码从web),以通过GUI O叼ect到fonction AsyncDumpTableToFile(这样我就可以修改GUI上的东西,但它崩溃说主线程使用和拥有它。

我怎么能打印有关飞奔任务的主界面informatoin(开始,运行,失败(异常信息),成功)?

同时,任何良好的阅读,我明白了更多这种东西?

所有最优秀的

文森特

+2

看看BackgroundWorker类。它具有监视进程和完成工作所需的一切:https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx –

+1

@Kevin:我不同意建议使用'BackgroundWorker'。这是一个足够体面的解决方案,并且由于时间长了,我承认有很多关于如何使用它的信息。但是现代C#代码将使用上面代码中的Task.Run()。此时的建议应该有助于推动OP,而不是落后。 –

+2

对于OP:您正在使用WPF,这意味着,在一般情况下,如果您将视图模型对象与“INotifyPropertyChanged”和数据绑定到UI,跨线程更新将自动处理。对于那些不起作用的场景,可以使用'Progress '报告进度,当然也可以通过'await'从任务方法返回对象。不幸的是,你的问题不包括一个可靠地再现你的问题的好的[mcve],所以不可能给你任何具体的建议或者一个好的答案(尽管你可能会得到很多不好的答案)。 –

回答

1

我与彼得同意,您理想的解决方案将使用MVVM。但是,您也可以直接访问UI元素与现代IProgress<T>为基础的方法,是这样的:

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"); 
} 

这种模式的重要组成部分是,Progress<T>对象必须而UI线程上创建。然后它会照顾你的线程编组。

+0

非常感谢,它运作良好。 –