Модераторы: Partizan, gambit

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> отрисовка формы 
V
    Опции темы
golfV
Дата 4.2.2010, 12:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



Доброго времени суток!

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

public  string FindFirst(SerialPort port, string first)
        {
            if (port.IsOpen != true)
            {
                initPort(port);
            }
            Thread thr = new Thread(delegate()
            {
                
                gt:;

                    string temp = "";
                    Application.DoEvents();
                    byte[] toSend1 = new byte[] { 0x1B, 0x50, 0x0D, 0x0A };
                    PortWrite(port, toSend1);
                    temp = port.ReadLine();
                    temp = parse(temp);
                    if (Convert.ToDouble(temp) > 2.0)
                    {
                        first = temp;
                    }
                    else
                    {
                        Thread.Sleep(2000);
                        goto gt;
                    }               
                
                });
            
                thr.IsBackground = true;
                thr.Start();
                return first;
 
        }

подскажите как можно сделать чтоб форма работала нармально пока выполняется метод?Если так возможно сделать.
PM MAIL   Вверх
KelTron
Дата 4.2.2010, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Используй BackgroundWorker и жизнь тебе покажется проще.



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
golfV
Дата 4.2.2010, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



с потоками совсем недавно начал работать, можеш какой нибудь простенький примерчик с BackgroundWorker показать?как его использовать в моем случае
PM MAIL   Вверх
Ronin08
Дата 4.2.2010, 14:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 218
Регистрация: 16.2.2008
Где: г.Москва

Репутация: 1
Всего: 1



--------------------
Зачем вставать рано или поздно? Надо вставать вовремя
PM MAIL   Вверх
golfV
Дата 4.2.2010, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



попробовал сделать с помощью BackgroundWorker. Но он мне неподходит. У меня два метода, при нажатии на кнопку вызывается первый метод, когда он получает результат тогда вызывается второй, второму методу надо передать результат который получил первый метод. А BackgroundWorker как я понял возвращает только 1 результат. Может есть какое нибудь другое решение или как нибудь можно заставить BackgroundWorker возвращать несколько результатов? Подскажите пожалуйста!!
PM MAIL   Вверх
Sfate
Дата 5.2.2010, 02:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Angry Beaver
*


Профиль
Группа: Участник
Сообщений: 111
Регистрация: 7.9.2008
Где: mov AL, BL

Репутация: нет
Всего: нет



щас меня затюкают smile 
Код

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

ставишь в начале... где у тебя обьявляются переменные...
--------------------
"Начинающий программист твердо уверен, что в 1 кбайте 1000 байт, а опытный точно знает, что в 1 километре 1024 метра..." © Unknown
PM MAIL WWW ICQ   Вверх
KelTron
Дата 5.2.2010, 05:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Цитата(golfV @  4.2.2010,  16:25 Найти цитируемый пост)
У меня два метода, при нажатии на кнопку вызывается первый метод, когда он получает результат тогда вызывается второй, второму методу надо передать результат который получил первый метод.

Ну и в чём проблема, объедини оба этих метода в один.



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
golfV
Дата 5.2.2010, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



вот мои два метода
Код

public  string FindFirst(SerialPort port, string first)
        {
            if (port.IsOpen != true)
            {
                initPort(port);
            }
            Thread thr = new Thread(delegate()
            {
                
                gt:;
                    string temp = "";                 
                    byte[] toSend1 = new byte[] { 0x1B, 0x50, 0x0D, 0x0A };
                    PortWrite(port, toSend1);
                    temp = port.ReadLine();
                    temp = parse(temp);
                    if (Convert.ToDouble(temp) > 2.0)
                    {
                        first = temp;
                    }
                    else
                    {
                        Thread.Sleep(2000);
                        goto gt;
                    }               
                
                });
            
                thr.IsBackground = true;
                thr.Start();
                thr.Join();  
                return first;
            
        }

Код

public string FindSecond(SerialPort port, string second, string firstw)
        {
            if (port.IsOpen != true)
            {
                initPort(port);
            }           
            
                Thread thr2 = new Thread(delegate()
               {
               gt1:
                   ;
                   string temp = "";
                   double descr = 0;
                   //  initPort(port);
                   byte[] toSend1 = new byte[] { 0x1B, 0x50, 0x0D, 0x0A };
                   PortWrite(port, toSend1);
                   temp = port.ReadLine();
                   temp = parse(temp);
                   temp = FindFirst(port, temp);
                   descr = Convert.ToDouble(temp) - Convert.ToDouble(firstw);
                   if (descr > 0.3)
                   {
                       second = temp;
                   }
                   else
                   {
                       Thread.Sleep(2000);
                       goto gt1;
                   }

               });

                thr2.IsBackground = true;
                thr2.Start();
                thr2.Join();            
                return second;

вот так я их вызываю
Код

TextBox1.Text = FindFirst(myPort, s1);
TextBox2.Text = FindSecond(myPort, s2, s1);


как мне кажется обьеденить их невозможно, так как результаты они заносят в разные текстбоксы

Это сообщение отредактировал(а) golfV - 5.2.2010, 09:57
PM MAIL   Вверх
KelTron
Дата 5.2.2010, 16:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Цитата(golfV @  4.2.2010,  16:25 Найти цитируемый пост)
второму методу надо передать результат который получил первый метод. 

Не вижу чтобы второй метод использовал результат первого. 

Цитата(golfV @  4.2.2010,  16:25 Найти цитируемый пост)
BackgroundWorker возвращать несколько результатов? Подскажите пожалуйста!!

У него результат object, значит чё угодно можно запихать, например:

Код

class Result 
{
    public string Res1 { get; set; }
    public string Res2 { get; set; }
}

void bwExecute_DoWork(object sender, DoWorkEventArgs e)
{
    var res = new Result();
    res.Res1 = FindFirst(myPort, s1);
    res.Res2 = FindSecond(myPort, s2, s1);

    e.Result = res;
}

void bwExecute_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    var res = e.Result as Result;
    TextBox1.Text = res.Res1;
    TextBox2.Text = res.Res2;
}






--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
golfV
Дата 5.2.2010, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



второму методу надо передать s1
Код

FindSecond(myPort, s2, s1);

которое возврашает первый метод
за пример с BackgroundWorker большое спасибо, буду пробовать

Это сообщение отредактировал(а) golfV - 5.2.2010, 17:00
PM MAIL   Вверх
KelTron
Дата 5.2.2010, 17:06 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Цитата(golfV @  5.2.2010,  16:58 Найти цитируемый пост)
второму методу надо передать s1

Если ты думаешь, что после выполнения FindFirst(myPort, s1) строка s1 изменяется, то ты ошибаешься. В метод передаётся копия ссылки на s1, котрая изменяется в методе, но оригинал это не затрагивает.



--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
golfV
Дата 5.2.2010, 17:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



Код

class Result 
{
    public string Res1 { get; set; }
    public string Res2 { get; set; }
}

void bwExecute_DoWork(object sender, DoWorkEventArgs e)
{
    var res = new Result();
    res.Res1 = FindFirst(myPort, s1);
    res.Res2 = FindSecond(myPort, s2, s1);

    e.Result = res;
}

void bwExecute_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    var res = e.Result as Result;
    TextBox1.Text = res.Res1;
    TextBox2.Text = res.Res2;
}



так тоже неполучается. Так как после того как первый метод закончил работу он должен передать значение текст боксу, только потом начинает работать второй метод. А щас получается что они все в начале отработаю потом только результаты появятся в текстбоксах. Всю голову уже сломал как это сделать smile 
PM MAIL   Вверх
KelTron
Дата 5.2.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Цитата(golfV @  5.2.2010,  17:08 Найти цитируемый пост)
Так как после того как первый метод закончил работу он должен передать значение текст боксу, только потом начинает работать второй метод.

Ну если это принципиально...
Сделать то не сложно, ты вот только скажи откуда у тебя берутся параметры: myPort, s2, s1? А то непонятно какой код там должен быть.

Добавлено через 14 минут и 23 секунды
В общем вот тебе пример набросал, думаю вопросы должны отпасть.

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  WindowsFormsApplication13.rar 36,35 Kb


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
golfV
Дата 5.2.2010, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



Ситуация такая, есть измерительное устроиство подключеное к компу, метод Findfirst каждые несколько секунд проверяет его 
на наличее нужной инфы, если получил нужную то записывает результат в переменую s1 и выводит в текстбокс, далее начинает работать второй метод FindSecond ему передается результат первого метода s1, когда метод получает нужную инфу он записывает второй результат в переменую s2.
Код

System.IO.Ports.SerialPort myPort = new System.IO.Ports.SerialPort("COM5", 1200, System.IO.Ports.Parity.Odd, 7, System.IO.Ports.StopBits.One);


в главном методе это все записывается последовательно записывается в текст боксы текстбоксы.Т.е пока первый метод несчитает нужную информацию с прибора метод будет выполняться также и второй. 
Код

string s1 = "";
string s2 = "";
                   s1 = FindFirst(myPort, s1);
                   textBox1.Text = s1;
                   

                   s2 = FindSecond(myPort, s2, s1);
                   textBox2.Text = s2;


Это сообщение отредактировал(а) golfV - 5.2.2010, 17:36
PM MAIL   Вверх
KelTron
Дата 5.2.2010, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Цитата(golfV @  5.2.2010,  17:33 Найти цитируемый пост)
s1 = FindFirst(myPort, s1);

А сначала по другому было..) 

Только вот смысла передавать s1 в метод FindFirst, также как и s2 в FindSecond нет никакого, потому что они там не изменяются и не используются.
Надо так:
Код

string s1 = FindFirst(myPort);
textBox1.Text = s1;
                   
string s2 = FindSecond(myPort, s1);
textBox2.Text = s2;


Ну и методы соответственно подкорректировать.

Это сообщение отредактировал(а) KelTron - 5.2.2010, 17:43


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
golfV
Дата 5.2.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



а мне кажется что нет ). Первому методу я передаю имя порта и пустую переменную, которую он мне вернёт после 
прохождения метода.
Код
 
FindFirst(myPort,s1);

и второму методу я также передую пустyю переменую s2 которую он мне вернет с результатом и переменую s1 с результатом 
первого метода чтоб с ней во втором методе сравнивать. 
Код

FindSecond(myPort, s2, s1);

Наверное я что то непонял)

Добавлено через 1 минуту и 22 секунды
в любом случае огромное спасибо за такие подробные примеры и советы.
PM MAIL   Вверх
KelTron
Дата 5.2.2010, 18:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 745
Регистрация: 8.10.2006
Где: Красноярск

Репутация: 9
Всего: 38



Сравним 2 метода:
Код

private string SomeFunc(string str)
{
    str = "123";
    return str;
}

private string SomeFunc()
{
    string str = "123";
    return str;
}

В чём недостатки первого:
1. Лишний бесполезный параметр.
2. Параметр используется как локальная переменная, что является признаком дурнопахнущего кода. Каждая переменная должна использоваться для одной цели, также и с параметрами - они нужны для получения информации, т.е. для чтения, если они явно не указаны как ref или out.

Несколько советов как нужно изменить метод FindFirst и по аналогии FindSecond
1. Нужно избавиться от кода с потоками(мы и так уже используем BackgroundWorker)
Код

public string FindFirst(SerialPort port, string first)
{
    if (port.IsOpen != true)
    {
        initPort(port);
    }

    gt:;
    string temp = "";
    byte[] toSend1 = new byte[] { 0x1B, 0x50, 0x0D, 0x0A };
    PortWrite(port, toSend1);
    temp = port.ReadLine();
    temp = parse(temp);
    if (Convert.ToDouble(temp) > 2.0)
    {
        first = temp;
    }
    else
    {
        Thread.Sleep(2000);
        goto gt;
    }

    return first;
}

2. Убираем ненужный параметр
Код

public string FindFirst(SerialPort port)
{
    if (port.IsOpen != true)
    {
        initPort(port);
    }

    gt:;
    string temp = "";
    byte[] toSend1 = new byte[] { 0x1B, 0x50, 0x0D, 0x0A };
    PortWrite(port, toSend1);
    temp = port.ReadLine();
    temp = parse(temp);
    if (Convert.ToDouble(temp) > 2.0)
    {
        return temp; //<---
    }
    else
    {
        Thread.Sleep(2000);
        goto gt;
    }
}

3. goto здесь не нужен, без него код понятнее
Код

public string FindFirst(SerialPort port)
{
    if (port.IsOpen != true)
    {
        initPort(port);
    }

    while (true)
    {
        string temp = "";
        byte[] toSend1 = new byte[] { 0x1B, 0x50, 0x0D, 0x0A };
        PortWrite(port, toSend1);
        temp = port.ReadLine();
        temp = parse(temp);
        if (Convert.ToDouble(temp) > 2.0)
        {
            return temp;
        }
        Thread.Sleep(2000);
    }
}







--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
golfV
Дата 6.2.2010, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 4.11.2007

Репутация: 1
Всего: 1



KelTron огромное спасибо за помощь сам бы несправился, сделал по твоему примеру с BackgroundWorker. Методы тоже поправил по твоему совету. Все работает отлично! еще раз спасибо!!!

Это сообщение отредактировал(а) golfV - 6.2.2010, 02:01
PM MAIL   Вверх
uranpro
Дата 6.2.2010, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 571
Регистрация: 7.5.2008
Где: Moscow city

Репутация: 1
Всего: 1



добавлю немного=)
для работы с контролами, созданными в других потоках следует использовать
Код

if (Control.InvokeRequired)
  Control.Invoke(new methodDelegat(method), methodArgs)

работа с потоками: Клац =)


--------------------
I want a perfect soul
PM MAIL ICQ   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0649 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.