2013-10-24 22 views
0

這是我已經擁有的代碼。如何使文本框的寫入功能起作用? (沒有凍結用戶界面)C#.NET 4 TPL

using System; 
using System.IO; 
using System.Collections.Generic; 
using System.Collections.Concurrent; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Documents; 
using System.Windows.Input; 
using System.Windows.Media; 
using System.Windows.Media.Imaging; 
using System.Windows.Navigation; 
using System.Windows.Shapes; 
using System.Threading; 
using System.Diagnostics; 

namespace ListInstaller 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 

     TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext(); 

     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void btnTarget_Click(object sender, RoutedEventArgs e) 
     { 
      System.Windows.Forms.FolderBrowserDialog fBD = new System.Windows.Forms.FolderBrowserDialog(); 
      fBD.RootFolder = Environment.SpecialFolder.Desktop; 
      fBD.ShowNewFolderButton = true; 
      fBD.Description = "Select the backup store folder."; 
      System.Windows.Forms.DialogResult result = fBD.ShowDialog(); 
      if (result == System.Windows.Forms.DialogResult.OK) 
      { 
       tbTarget.Text = fBD.SelectedPath; 
      } 
     } 

     private void btnDestination_Click(object sender, RoutedEventArgs e) 
     { 
      System.Windows.Forms.FolderBrowserDialog fBD = new System.Windows.Forms.FolderBrowserDialog(); 
      fBD.RootFolder = Environment.SpecialFolder.Desktop; 
      fBD.ShowNewFolderButton = true; 
      fBD.Description = "Select the backup store folder."; 
      System.Windows.Forms.DialogResult result = fBD.ShowDialog(); 
      if (result == System.Windows.Forms.DialogResult.OK) 
      { 
       tbDestination.Text = fBD.SelectedPath; 
      } 
     } 

     private void btnCSVSource_Click(object sender, RoutedEventArgs e) 
     { 
      Microsoft.Win32.OpenFileDialog opFD = new Microsoft.Win32.OpenFileDialog(); 
      opFD.DefaultExt = ".csv"; 
      opFD.Filter = "CSV Files (*.csv)|*.csv"; 
      opFD.InitialDirectory = "D:\\"; 
      Nullable<bool> result = opFD.ShowDialog(); 
      if (result == true) 
      { 
       string filename = opFD.FileName; 
       tbCSVSource.Text = filename; 
      } 
     } 

     private void cbBackup_Checked(object sender, RoutedEventArgs e) 
     { 
      btnDestination.Visibility = Visibility.Visible; 
      lblDestination.Visibility = Visibility.Visible; 
      tbDestination.Visibility = Visibility.Visible; 
      tbMainLog.AppendText("\nSwitching to Back Up Mode. @ " + DateTime.Now); 
     } 

     private void cbBackup_Unchecked(object sender, RoutedEventArgs e) 
     { 
      btnDestination.Visibility = Visibility.Hidden; 
      lblDestination.Visibility = Visibility.Hidden; 
      tbDestination.Visibility = Visibility.Hidden; 
      tbMainLog.AppendText("\nSwitching to Normal Mode. @ " + DateTime.Now); 
     } 

     private void List_Installer_Loaded(object sender, RoutedEventArgs e) 
     { 
      DateTime currTime = DateTime.Now; 
      tbMainLog.Text = "Started at " + currTime; 
     } 

     private void tbMainLog_TextChanged(object sender, TextChangedEventArgs e) 
     { 
      tbMainLog.ScrollToEnd(); 
     } 

     private void btnInstall_Click(object sender, RoutedEventArgs e) 
     { 
      Stopwatch timer = Stopwatch.StartNew(); 
      List<Task> tasks = new List<Task>(); 
      BlockingCollection<string[]> data = new BlockingCollection<string[]>(); 

      Task install = Task.Factory.StartNew(() => installAndLog(data)); 

      string filepath = tbCSVSource.Text; 
      Task parse = Task.Factory.StartNew(() => 
       { 
        CSVParser csvpParser = new CSVParser(filepath); 
        data = csvpParser.parsedDate(); 
        data.CompleteAdding(); 
       }); 
      tasks.Add(parse); 

      Task.Factory.ContinueWhenAll(tasks.ToArray(), 
       result => 
       { 
        Int64 time = timer.ElapsedMilliseconds; 
        //foreach(string[] row in data.GetConsumingEnumerable()) 
        //{ 
        // string netbookName = row[0]; 
        // string boxNumber = row[1]; 
        // tbMainLog.Text += "\n"; 
        // tbMainLog.Text += "Netbook: " + netbookName + "\t"; 
        // tbMainLog.Text += "Box Number: " + boxNumber + "\t"; 
        //} 
        tbMainLog.Text += "\nTime taken: "; 
        tbMainLog.Text += time.ToString() + "milliseconds"; 
       }, CancellationToken.None, TaskContinuationOptions.None, ui); 
     } 

     private void installAndLog(BlockingCollection<string[]> data) 
     { 
      foreach (string[] row in data.GetConsumingEnumerable()) 
      { 
       string netbookName = row[0]; 
       string boxNumber = row[1]; 
       Task.Factory.StartNew(new Action(() => 
        { 
         tbMainLog.Text += "\n"; 
         tbMainLog.Text += "Netbook: " + netbookName + "\t"; 
         tbMainLog.Text += "Box Number: " + boxNumber + "\t"; 
         tbErrors.AppendText(boxNumber + " -- " + netbookName + " File Not Found.\n"); 
        }), CancellationToken.None, TaskCreationOptions.None, ui); 
      } 
     } 
    } 
} 

我想做什麼就能做的是調用installAndLog()函數,而凍結 UI。我對C#多線程編碼非常陌生。 我將在installAndLog()函數中執行文件副本,並希望能夠實時查看發生了什麼。 CSV文件結構如下:

netbook1,file1 
netbook2,file2 
etc.... 

感謝您的幫助。

回答

0

您需要刪除ui變量,因爲它將任務同步到導致ui鎖定的ui線程上。

然後,您需要將所有調用包裝到一個invokeRequired模式中的UI控件。 的細節link看到這個

編輯: 給予這不是WinForms的,如果你真的想成爲適得其反,你可以做同樣的與調度

你應該seriosly看看MVVM模式而不是:

+0

是invokeRequired窗體不是wpf? – user2917005

+0

你沒有說明你在哪裏使用什麼技術,而你使用的方法看起來像winforms。在WPF中,您將使用MVVM模式和數據綁定。數據綁定將處理從另一個線程更新控件的線程問題。 –

相關問題