2012-03-04 77 views
0

我有一个列表框,我把一些文件,如果文件不是AVI我自动转换,但我希望在文件转换消息将这些文件现在转换到另一个标签上写格式,现在会发生什么,在我看来,只有当程序已完成将它们转换其更新标签,而不是在这个过程中调度没有及时更新标签

所有修补程序后:

private void btnAdd_Click(object sender, RoutedEventArgs e) 
{ 
    btnPlay.IsEnabled = false; 
    Stream checkStream = null; 
    Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog(); 
    openFileDialog.Multiselect = true; 
    openFileDialog.InitialDirectory = "c:\\"; 
    openFileDialog.Filter = "All files (*.*)|*.*"; 
    openFileDialog.FilterIndex = 1; 
    openFileDialog.Title = "Please Select Source File"; 

    if ((bool)openFileDialog.ShowDialog()) 
    { 
     if ((checkStream = openFileDialog.OpenFile()) != null) 
     { 
      foreach (string file in openFileDialog.FileNames) 
      { 
       try 
       { 
        FileInfo fileInfo = new FileInfo(file); 
        listBoxFiles.Items.Add(file); 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show("Error: Could not read file from disk. Original error: " + ex.Message); 
       } 
      } 

      for (int i = 0; i < listBoxFiles.Items.Count; i++) 
      { 
       string path = (string)listBoxFiles.Items[i]; 
       FileInfo fileInfo = new FileInfo(path); 

       if (fileInfo.Extension != ".AVI") 
       { 
        listToRemove.Add(path); 
       } 
      } 

      (new System.Threading.Thread(ProcessAviFiles)).Start(); 

      foreach (string file in listToRemove) //remove all non .AVI files from listbox 
      { 
       listBoxFiles.Items.Remove(file); 
      } 
     } 
    } 
    else 
    { 

    } 

    if (listBoxFiles.Items.Count != 0) 
    { 
     btnClear.IsEnabled = true; 
     btnPlay.IsEnabled = true; 
    } 

    listToRemove.RemoveRange(0, listToRemove.Count); 

} 

功能:

public void ProcessAviFiles() 
{ 
    if (listToRemove.Count == 0) 
    { 
     return; 
    } 

    lblStatus2.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() => { lblStatus2.Content = "Convert file to .AVI..."; })); 

    foreach (String file in listToRemove) 
    { 
     FileInfo fileInfo = new FileInfo(file); 
     editpcap = new EditCap(fileInfo); 
     String newFileName = editpcap._newFileName; 
     Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(() => 
      { 
       listBoxFiles.Items.Add(editpcap._newFileName); 
      })); 
    } 

    lblStatus2.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new Action(
     () => 
    { 
     lblStatus2.Content = "Select adapter and packet file, Click play button to start."; 
     btnClear.IsEnabled = true; 
    })); 
} 

回答

2

标签没有更新,因为主UI线程忙于做其他事情。

展望你的代码,似乎你正在运行的主UI线程内的AVI文件转换业务。您应该在单独的线程中运行耗时的任务,以确保您的UI保持响应。

下面是一个修复您的问题,更换您的foreach (String file in listToRemove){}由:

Action aviConversion = new Action(() => { 
    if(listToRemove.Count == 0) return; // nothing to do 
    lblStatus2.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
           new Action(() => { lblStatus2.Content = "Convert file to .AVI...";}); 
     ); 
    foreach (String file in listToRemove){ 
     FileInfo fileInfo = new FileInfo(file); 
     editpcap = new (classes who convert the files)(fileInfo); 
     String newFileName = editpcap._newFileName; 
     Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
           new Action(() => { 
           listBoxFiles.Items.Add(newFileName); 
     })); 
    } 
    lblStatus2.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
           new Action(() => { lblStatus2.Content = "AVI file conversion finished...";}); 
}); 
// Run this action in a separate thread... 
Task.Factory.StartNew(action, "beta"); 

编辑使用的Thread代替Task(OP不能使用Task

private void ProcessAviFiles(){ 
     if(listToRemove.Count == 0) return; // nothing to do 
     lblStatus2.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
            new Action(() => { lblStatus2.Content = "Convert file to .AVI...";}); 
      ); 
     foreach (String file in listToRemove){ 
      FileInfo fileInfo = new FileInfo(file); 
      editpcap = new (classes who convert the files)(fileInfo); 
      String newFileName = editpcap._newFileName; 
      Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
           new Action(() => { 
           listBoxFiles.Items.Add(newFileName); 
      })); 
     } 
     lblStatus2.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, 
            new Action(() => { lblStatus2.Content = "AVI file conversion finished...";}); 
} 

取代你foreach (String file in listToRemove){}由:

(new System.Threading.Thread(ProcessAviFiles)).Start(); 
+0

我不能使用任务,因为我使用.Net 3.5,并且无法升级到.Net 4,因为它的计算机来自我的工作,而且它不那么容易。 – user979033 2012-03-04 17:58:10

+0

@ user979033好的,只是更新了我的帖子。请参阅我的编辑。 – GETah 2012-03-04 18:09:01

+0

现在它确定,但程序崩溃在这里:listBoxFiles.Items.Add(editpcap._newFileName);在函数ProcessAviFiles()中出现错误“调用线程不能访问此对象,因为不同的线程拥有它。”这是我的问题从一开始 – user979033 2012-03-04 18:24:22

0

使用的BackgroundWorker的主要任务和调度的UI更新。

backgroundWorker1.DoWork += worker_DoWork; 
backgroundWorker1.RunWorkerCompleted += worker_RunWorkerCompleted; 
backgroundWorker1.WorkerReportsProgress = true; 
backgroundWorker1.WorkerSupportsCancellation = true;   
backgroundWorker1.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);