Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Потоки и backgroundworker


Автор: Neymexa 4.5.2009, 21:33
не получается применить компонент backgroundworker к моей проге.
прога считывает файлы из директории , сравнивает их с условием .
код позже...

Автор: -Mikle- 5.5.2009, 08:19
Цитата(Neymexa @  5.5.2009,  00:33 Найти цитируемый пост)
код позже

А зачем топик завел то? Место забил чтоль?  smile  Давай код который сделал, а потом разберемся что в нем не так.

Автор: Neymexa 5.5.2009, 20:35
Код

namespace WindowsFormsApplication_test_
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            toolStripProgressBar1.Visible = false;
            toolStripStatusLabel1.Visible = false;
            //Control.CheckForIllegalCrossThreadCalls = false; //это необходимо для того, что бы разрешить межпотоковые вызовы для управления визуальными элементами на форме
            //sTh = new Thread(new ThreadStart(XMLWorker)); //создаем параллельный поток из нашего метода
        }

        private void button2_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();
            textBox1.Text = folderBrowserDialog1.SelectedPath;
        }
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            toolStripProgressBar1.Value = e.ProgressPercentage;//процент выполнения
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Thread t = new Thread(XMLMove);
            backgroundWorker1.RunWorkerAsync(XMLMove());
            button1.Enabled = false;
            while (this.backgroundWorker1.IsBusy)
            {
                Application.DoEvents();
            }
            button1.Enabled = true;

        }

        private void XMLMove(object sender, DoWorkEventArgs e)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(textBox1.Text);
                FileInfo[] array = di.GetFiles("*.xml");
                for (int i = 0; i < array.Length; i++)
                {
                    bool zn = true;
                    XPathDocument doc = new XPathDocument(textBox1.Text + "\\" + array[i]);
                    XPathNavigator navigator = doc.CreateNavigator();

                    for (int j = 0; j < listView1.Items.Count; j++)
                    {
                        XPathNodeIterator nodes = navigator.Select(listView1.Items[j].SubItems[1].Text);
                        if (nodes.MoveNext())
                        {
                            toolStripProgressBar1.Maximum = i;
                            toolStripProgressBar1.Value = i;
                            toolStripProgressBar1.Visible = true;
                            toolStripStatusLabel1.Visible = true;
                            toolStripStatusLabel1.Text = "Идет перемещение из" + textBox1.Text + " в " + listView1.Items[j].Text;
                            File.Move(textBox1.Text + "\\" + array[i], listView1.Items[j].Text + "\\" + array[i]);
                            zn = false;

                            break;
                        }
                    }
                    if (zn == true)
                    {
                        //MessageBox.Show("naideno");
                        File.Move(textBox1.Text + "\\" + array[i], @"C:\Users\User" + "\\" + array[i]);
                        toolStripStatusLabel1.Text = "Идет перемещение из" + textBox1.Text + " в " + @"C:\Users\User";

                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            } 
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }
    }
}


вот код пытаюсь применить прочитанное так что не судите за пустой метод backgroundWorker1_RunWorkerCompleted

Автор: -Mikle- 5.5.2009, 20:47
Код посмотрел, вроде ошибок нет. Что не работает? Что не получается?

Автор: Любитель 5.5.2009, 20:55
Брр.. Почитайте как работать с BackgroundWorker-ом smile

1. Параметр в RunWorkerAssync - это опциональный аргумент для передачи в фоновый поток. А не делегат-обработчик.
2. То, что будет делаться в фоновом потоке задаётся с помощью обработчика DoWork.
3. Обращаться к контролам в этом обработчике вообще говоря нельзя. Только через Invoke - но лучше юзать ReportProgress метод вашего воркера. И соответствующий обработчик.
4. Завершающие действия выполняются в RunWorkerCompleted, а не тут же после запуска фонового потока.

А всякие DoEvents - да, можно написать ваш код однопоточно (что у вас почти и есть). Но BackgroundWorker предназначен совсем не для этого.

Автор: Neymexa 5.5.2009, 20:57
код сам работает только нужно применить компонент backgroundworker чтобы создать фоновый поток и в нем делать все что описано в XMLMove.чтобы при перемещении файлов если их будет много чтобы форма не подвисала

Я понятно объяснил?

Автор: -Mikle- 5.5.2009, 21:41
Вот теперь понятно.

Вот вам упрощенный пример, без применения вашей задачи:
Код

        // из-за того, что нельзя использовать компоненты формы из другого потока,
        // но при этом есть необходимость передать какие-то параметры с формы в фоновый поток,
        // для этого можно объявить структуру или класс.
        struct BackgroundWorkParams
        {
            // эти поля я объявил для примера, используй свои поля, которые тебе нужно передать.
            public string Param1;
            public int Param2;
            public List<string> SomeList;
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            backgroundWorker1.WorkerReportsProgress = true;

            // заполняем все нужные поля
            BackgroundWorkParams param = new BackgroundWorkParams();
            param.Param1 = ".......";

            // запускаем на выполнение
            btnStart.Enabled = false;
            backgroundWorker1.RunWorkerAsync(param);
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // получаем все переданные параметры
            BackgroundWorkParams param = (BackgroundWorkParams)e.Argument;

            // для простоты примера, имитируем длинное выполнение
            // реально вставь свой код вместо этого
            for (int i = 0; i < 100; i++)
            {
                System.Threading.Thread.Sleep(100);

                // сообщаем о прогрессе
                backgroundWorker1.ReportProgress(i + 1);
            }

            e.Result = "successfully";
        }

        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBar1.Value = e.ProgressPercentage;
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnStart.Enabled = true;

            if (e.Error != null)
                MessageBox.Show("Произошла ошибка: " + e.Error.Message);
            else
                MessageBox.Show("Завершено успешно. Результат выполнения: " + Convert.ToString(e.Result));
        }

Автор: Neymexa 5.5.2009, 21:48
Цитата(Любитель @ 5.5.2009,  20:55)
Брр.. Почитайте как работать с BackgroundWorker-ом smile

1. Параметр в RunWorkerAssync - это опциональный аргумент для передачи в фоновый поток. А не делегат-обработчик.
2. То, что будет делаться в фоновом потоке задаётся с помощью обработчика DoWork.
3. Обращаться к контролам в этом обработчике вообще говоря нельзя. Только через Invoke - но лучше юзать ReportProgress метод вашего воркера. И соответствующий обработчик.
4. Завершающие действия выполняются в RunWorkerCompleted, а не тут же после запуска фонового потока.

А всякие DoEvents - да, можно написать ваш код однопоточно (что у вас почти и есть). Но BackgroundWorker предназначен совсем не для этого.

все что ты советуешь я прочитал но применить не получается -  не судите строго - начинающий

Добавлено через 5 минут и 38 секунд
Mikle спасибо ща постмотрю...
public List<string> SomeList - про эти скобки тоже надо почитать 

Автор: AGENTxXx 8.6.2009, 00:52
ВСЕМ ПРИВЕТ! У меня вот какая проблема: не получается сделать так, чтобы при прослушки данного порта и ip адреса сервер не вис. В общем все работает нормально. Клиенты с сервером хорошо взаимодействуют. Но нужно чтобы в listbox который находится на серверной части хотя бы писалось: клиент подключился/клиент отключился. Погуглил и понял что скорее всего надо делать через BackgroundWorker, но не представляю как это сделать. Не можете подсказать или хотя бы какой ни будь простой пример привести. Буду ОЧЕНЬ благодарен!!!

Автор: KelTron 8.6.2009, 05:05
http://wladm.narod.ru/C_Sharp/backgroundwork.html

Автор: AGENTxXx 8.6.2009, 10:22
Большое спасибо! Сегодня думаю тогда уже допрогаю)))

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)