Диспетчер не обновил ярлык - PullRequest
0 голосов
/ 04 марта 2012

У меня есть 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;
    }));
}

Ответы [ 2 ]

2 голосов
/ 04 марта 2012

Метка не обновляется, потому что основной поток пользовательского интерфейса занят другими делами.

Глядя на ваш код, кажется, что вы запускаете бизнес по конвертации AVI-файлов внутри основного потока пользовательского интерфейса. Вы должны запустить эту трудоемкую задачу в отдельном потоке, чтобы убедиться, что ваш интерфейс остается отзывчивым

Ниже приведено исправление вашей проблемы, замените 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 голосов
/ 04 апреля 2014

Используйте BackgroundWorker для основной задачи и диспетчер обновлений пользовательского интерфейса.

 backgroundWorker1.DoWork += worker_DoWork;
 backgroundWorker1.RunWorkerCompleted += worker_RunWorkerCompleted;
 backgroundWorker1.WorkerReportsProgress = true;
 backgroundWorker1.WorkerSupportsCancellation = true;          
 backgroundWorker1.ProgressChanged +=new ProgressChangedEventHandler(backgroundWorker1_ProgressChanged); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...