我有一个ListBox,我放了一些文件,如果文件不是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;
}));
}
答案 0 :(得分: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();
答案 1 :(得分:0)
将BackgroundWorker用于主要任务和调度程序以进行UI更新。
backgroundWorker1.DoWork += worker_DoWork;
backgroundWorker1.RunWorkerCompleted += worker_RunWorkerCompleted;
backgroundWorker1.WorkerReportsProgress = true;
backgroundWorker1.WorkerSupportsCancellation = true;
backgroundWorker1.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged);