2013-11-03 122 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