Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > Общие вопросы .NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.04.2009, 21:13   #1
Neymexa
Proffesional
Форумчанин
 
Аватар для Neymexa
 
Регистрация: 18.11.2008
Сообщений: 417
По умолчанию Работа с потоками

Код:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Xml.XPath;
using System.Xml;

namespace WindowsFormsApplication_test_
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                listBox1.Items.Clear();
                folderBrowserDialog1.ShowDialog();
                textBox1.Text = folderBrowserDialog1.SelectedPath;
                DirectoryInfo di = new DirectoryInfo(textBox1.Text);
                FileInfo[] array = di.GetFiles();
                foreach (FileInfo sp in array)
                {
                    if (sp.Extension == ".xml")
                    {
                        listBox1.Items.Add(sp.Name);
                    }
                }

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

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {                
                DirectoryInfo di = new DirectoryInfo(textBox1.Text);
                FileInfo[] array = di.GetFiles();
                


                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    
                    XPathDocument doc = new XPathDocument(textBox1.Text+ "\\" + listBox1.Items[i]);
                    XPathNavigator navigator = doc.CreateNavigator();
                    XPathNodeIterator nodes = navigator.Select("/bookstore/book");
                    //MessageBox.Show(File.ReadAllText(listBox1.Items[i].ToString()));// содержимое xml файлов
                    if (nodes.MoveNext())
                    {
                            //MessageBox.Show(nodes.Current.Name);вывод заданного узла
                            foreach (FileInfo sp in array)
                            {
                                if (sp.Extension == ".xml")
                                {
                                    if (nodes.MoveNext())
                                    {
                                        if (nodes.MoveNext())
                                        {
                                            //listBox1.Items.Add(sp.FullName);
                                            toolStripStatusLabel1.Text = "Идет перемещение "+listBox1.Items[i]+" Из "+textBox1.Text+" в "+textBox3.Text;
                                            File.Move(textBox1.Text + "\\" + listBox1.Items[i], textBox3.Text + "\\" + listBox1.Items[i]);
                                            //MessageBox.Show(textBox2.Text +"\\" + name);
                                        }
                                    }
                                }
                            }

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

        }

        private void button3_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.ShowDialog();
            textBox3.Text = folderBrowserDialog1.SelectedPath;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            toolStripStatusLabel1.Text="";
            //toolStripProgressBar1.Visible = false;
            
        }


    }
}
У меня данная прога работает с xml если их будет много примерно 1000 то форма будет подвисать .
как сделать 2 потока - 1 отвечает за форму другой за сам процесс переборки xml?

заранее спс
О, степь родимая, как я скучаю по тебе...
Neymexa вне форума Ответить с цитированием
Старый 20.04.2009, 21:40   #2
oleg kutkov
Unix C++ developer
Форумчанин
 
Аватар для oleg kutkov
 
Регистрация: 16.04.2007
Сообщений: 651
По умолчанию

Необходимо код, отвечающий за работу с XML поместить в отдельный метод (вообще советую не вешать в обработчики событий кнопок и т.п. большие куски кода, лучше оформлять их как отдельные методы, так универсальнее и удобнее, что ли, можно вызывать отдельно, без события...)
вообщем получаем:

Самое главное в начале:

Код:
using System.Threading; //подключаем сборку для работы с потоками
Код:
private void XMLWorker()  //метод для обработки XML
 {
            try
            {                
                DirectoryInfo di = new DirectoryInfo(textBox1.Text);
                FileInfo[] array = di.GetFiles();
                
                for (int i = 0; i < listBox1.Items.Count; i++)
                {
                    
                    XPathDocument doc = new XPathDocument(textBox1.Text+ "\\" + listBox1.Items[i]);
                    XPathNavigator navigator = doc.CreateNavigator();
                    XPathNodeIterator nodes = navigator.Select("/bookstore/book");
                    //MessageBox.Show(File.ReadAllText(listBox1.Items[i].ToString()));// содержимое xml файлов
                    if (nodes.MoveNext())
                    {
                            //MessageBox.Show(nodes.Current.Name);вывод заданного узла
                            foreach (FileInfo sp in array)
                            {
                                if (sp.Extension == ".xml")
                                {
                                    if (nodes.MoveNext())
                                    {
                                        if (nodes.MoveNext())
                                        {
                                            //listBox1.Items.Add(sp.FullName);
                                            toolStripStatusLabel1.Text = "Идет перемещение "+listBox1.Items[i]+" Из "+textBox1.Text+" в "+textBox3.Text;
                                            File.Move(textBox1.Text + "\\" + listBox1.Items[i], textBox3.Text + "\\" + listBox1.Items[i]);
                                            //MessageBox.Show(textBox2.Text +"\\" + name);
                                        }
                                    }
                                }
                          }       
                     }                   
                }
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
 }
Объявляем где нибудь в начале такую переменную:

Код:
Thread sTh;
И теперь запускаем эту функцию в другом потоке, для этого, сначала, на обработчик загрузки формы вешаем такой код:

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

Код:
private void button2_Click(object sender, EventArgs e)
 {
   if(sTh.ThreadState == ThreadState.Unstarted) //смотрим, не запущен ли уже поток
      sTh.Start(); // если нет - стартуем
 }

Последний раз редактировалось oleg kutkov; 20.04.2009 в 21:46.
oleg kutkov вне форума Ответить с цитированием
Старый 21.04.2009, 09:08   #3
neomichi
Пользователь
 
Регистрация: 26.03.2009
Сообщений: 43
По умолчанию

еще бы хотел сказать , думаю все таки втему сорри если нет.
еще очень важный момент, нельзя обратиться из одного потока к элементу созданному в другом потоке..или типо того, поэтому используем делегаты.Как писали до меня...
Код:
 Control.CheckForIllegalCrossThreadCalls = false;
помоему это не есть гуд, используйте делегаты =)))

Последний раз редактировалось neomichi; 21.04.2009 в 09:17.
neomichi вне форума Ответить с цитированием
Старый 21.04.2009, 22:06   #4
Neymexa
Proffesional
Форумчанин
 
Аватар для Neymexa
 
Регистрация: 18.11.2008
Сообщений: 417
По умолчанию

oleg kutkov огромное спасибо - расписал подробно почти каждую строку кода(особенно ценю совет вначале - такое в книгах врят ли пишут) кроме 1-ой ,а neomichi как раз еще более подробно объяснил.
О, степь родимая, как я скучаю по тебе...

Последний раз редактировалось Neymexa; 21.04.2009 в 22:08.
Neymexa вне форума Ответить с цитированием
Старый 21.04.2009, 22:24   #5
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

у меня есть небольшой вопрос по потокам

есть форма. На ней расположены 2 кнопки (старт, стоп) и прогрессбар.
при нажатии на кнопку старт создаётся и запускается поток.
Код:
Thread t = new Thread(new ThreadStart(run));
t.Start();
в этом потоке производятся вычисления.
при попытке изменить из потока значение progressbar1.Value компилятор ругается, что прогрессбар находится в другом потоке.
вопрос: как изменять значение прогрессбара из потока t?
Life if about choices
Make the right choice
TaTT DoGG вне форума Ответить с цитированием
Старый 21.04.2009, 22:50   #6
Neymexa
Proffesional
Форумчанин
 
Аватар для Neymexa
 
Регистрация: 18.11.2008
Сообщений: 417
По умолчанию

Цитата:
Сообщение от TaTT DoGG Посмотреть сообщение
у меня есть небольшой вопрос по потокам

есть форма. На ней расположены 2 кнопки (старт, стоп) и прогрессбар.
при нажатии на кнопку старт создаётся и запускается поток.
Код:
Thread t = new Thread(new ThreadStart(run));
t.Start();
в этом потоке производятся вычисления.
при попытке изменить из потока значение progressbar1.Value компилятор ругается, что прогрессбар находится в другом потоке.
вопрос: как изменять значение прогрессбара из потока t?
ты это читал?
нельзя обратиться из одного потока к элементу созданному в другом потоке
проверь чтобы все методы были в одном потоке или используй делегаты (но здесь я тебе не помощник - я сам не особо силен)

выложи весь код и вообще лучше создать новую тему
О, степь родимая, как я скучаю по тебе...
Neymexa вне форума Ответить с цитированием
Старый 21.04.2009, 23:57   #7
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

Цитата:
Сообщение от Neymexa Посмотреть сообщение
нельзя обратиться из одного потока к элементу созданному в другом потоке
знаю, поэтому и спршиваю как достучаться до объекта другого потока

Цитата:
Сообщение от Neymexa Посмотреть сообщение
и вообще лучше создать новую тему
зачем создавать лишнюю?

Код:
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Thread h;

        private void run()
        {          
            int s = 0;
            for (int i = Convert.ToInt32(textBox1.Text); i <= Convert.ToInt32(textBox2.Text); i++)
            {
                s += i;
                //тут нужно изменять progressbar1.Value
            }
            MessageBox.Show(Convert.ToString(s));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            h = new Thread(new ThreadStart(run));
            h.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            h.Abort();
        }
    }
}
Life if about choices
Make the right choice

Последний раз редактировалось TaTT DoGG; 22.04.2009 в 00:01.
TaTT DoGG вне форума Ответить с цитированием
Старый 22.04.2009, 00:30   #8
oleg kutkov
Unix C++ developer
Форумчанин
 
Аватар для oleg kutkov
 
Регистрация: 16.04.2007
Сообщений: 651
По умолчанию

Ну как бы можно опять так же:

Код:
Control.CheckForIllegalCrossThreadCalls = false;
Это всего лишь заставляет компилятор не следить за такими межпоточными вызовами, от возможных ошибок не убережет...
oleg kutkov вне форума Ответить с цитированием
Старый 22.04.2009, 00:35   #9
TaTT DoGG
Форумчанин
 
Аватар для TaTT DoGG
 
Регистрация: 25.04.2008
Сообщений: 476
По умолчанию

этот вариант я уже рассматривал и он меня не устраивает ((
Life if about choices
Make the right choice
TaTT DoGG вне форума Ответить с цитированием
Старый 22.04.2009, 08:51   #10
OrdJONY
.NET-чик
Форумчанин
 
Аватар для OrdJONY
 
Регистрация: 24.03.2007
Сообщений: 569
По умолчанию

Цитата:
Сообщение от TaTT DoGG Посмотреть сообщение
у меня есть небольшой вопрос по потокам

есть форма. На ней расположены 2 кнопки (старт, стоп) и прогрессбар.
при нажатии на кнопку старт создаётся и запускается поток.
Код:
Thread t = new Thread(new ThreadStart(run));
t.Start();
в этом потоке производятся вычисления.
при попытке изменить из потока значение progressbar1.Value компилятор ругается, что прогрессбар находится в другом потоке.
вопрос: как изменять значение прогрессбара из потока t?
Для вашей цели вполне хватит BackgroundWorker-а, о нем уже была тема на форуме. А так вам нужно синхронизировать потоки, для wpf я могу написать как
"Разработка под веб - как работа с пылесосом: нихрена не прикольно, но засасывает"
Мо маленький городок
OrdJONY вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с аудио (потоками) JamS007 Общие вопросы C/C++ 2 14.02.2009 22:14
Проблема с потоками DeeNamid Общие вопросы Delphi 2 04.08.2008 17:36
работа с потоками Alex_Pro Общие вопросы .NET 1 01.07.2008 07:25
C++, работа с потоками mat90x Помощь студентам 20 15.05.2008 22:20
Проблема с потоками vitalik007 Общие вопросы Delphi 1 11.03.2008 22:35