2013-11-03 154 views
0

我移动文件与file.move队列锁在C#中的GUI

foreach(file){ 
file.move(file,dst);} 

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

+1

做你的BackgroundWorker的工作,或异步,这样你就不会阻止你的UI线程。更多信息在这里:http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx – etaiso

+0

看看这个问题,并回答http://stackoverflow.com/questions/5483565/how- to-use-wpf-background-worker :)。 –

+0

谢谢!我是否需要为每个步骤单独使用BackgroundWorker?或者只有一名工作人员让GUI响应? – Kassan

回答

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

最好是配置TaskScheduler.FromCurrentSynchronizationContext,以避免在UpdateStatus方法中更新UI对象时的异常。 – Oleg

2

卡桑,我觉得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