file.move队列锁定gui in c#

时间:2013-11-03 11:35:43

标签: c# file-copying

我用

移动文件
foreach(file){
file.move(file,dst);}

我希望在移动每个文件(不同分区)后使用有关进度的信息更新表单。不幸的是,我的WPF表单在整个复制/移动队列中很忙。我尝试了InvalidateVisual(),没有成功 - 我可以做些什么来确保在移动文件期间(或之后)的GUI响应?

2 个答案:

答案 0 :(得分:2)

Kasan,我认为BackgroundWorker对你有用。任务是很好的方法,但是要从任务更新UI进度,您需要打扰调度事件到UI线程,否则您将获得异常,因为不允许从UI以外的线程更新UI。 以下是文档的示例和链接

 public partial class MainWindow : Window
{
    BackgroundWorker _worker = new BackgroundWorker();
    public MainWindow()
    {
        InitializeComponent();
        _worker = new BackgroundWorker();
        _worker.DoWork += worker_DoWork;
        _worker.ProgressChanged += worker_ProgressChanged;
    }

    void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progress1.Value = e.ProgressPercentage;
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        _worker.RunWorkerAsync();
    }

    void worker_DoWork(object sender, DoWorkEventArgs e)
    {
        var files = new List<string>();
        foreach(var file in files)
        {
            File.Move(file, /*target*/);
            _worker.ReportProgress(/* here is progress from 0 to 100 */)
        }
    }
}

BackgroundWorker Sample

答案 1 :(得分:0)

如果您希望保持GUI响应,您应该开始执行这项长任务的新线程。

这样,您的GUI线程不会被这个长时间的操作阻止。

class example
{
    static void UpdateStatus(int i)
    {
        // UpdateStatus
        Console.WriteLine(i + "Done!");
    }

    static void Main(string[] args)
    {
        int state = 0;
        Task t = Task.Run(
              () =>
              {
                  // do your stuff - this is going to run async
                  for (int i = 0; i < 10; i++)
                      file.move(file,dst);
                      UpdateStatus(i); // callback to update status 
                  }
              }
            );
        Console.WriteLine("Started"); // You wont block this code by running the async part
        t.Wait(); 
        Console.WriteLine("DONE");
        Console.ReadKey();

    }
}

在你的情况下,你可以这样使用:

        Task t = Task.Run(
              () =>
              {
                  // do your stuff - this is going to run async
                  foreach(File file in Files){
                  {
                      move(file);
                      UpdateStatus(i); // callback to update status (eg.:how many files have been moved yet)
                  }
              }
            );