2013-10-24 21 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模式和数据绑定。数据绑定将处理从另一个线程更新控件的线程问题。 –

相关问题