0

这是我已经拥有的代码。

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

我想做的是在不冻结 UI 的情况下调用 installAndLog() 函数。我对 C# 多线程编码非常陌生。我将在 installAndLog() 函数中进行文件复制,并希望能够实时查看正在发生的事情。csv文件结构如下:

netbook1,file1
netbook2,file2
etc....

谢谢你的帮助。

4

1 回答 1

0

您需要删除 ui 变量,因为它正在将任务同步到 ui 线程上,从而导致 ui 锁定。

然后,您需要将所有对 ui 控件的调用包装在 invokeRequired 模式中。有关详细信息,请参阅此链接

编辑:给这不是winforms,如果你真的想适得其反,你可以用Dispatcher做同样的事情

你应该认真看看 MVVM 模式:

于 2013-10-24T19:34:33.280 回答