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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема незавершения потока, C# WinFrom 
:(
    Опции темы
Mutronics
Дата 11.7.2007, 13:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Вобщем на форме есть TabControl и при каждом нажатии открывается новая страница с выполнением следующего кода:
Код

trd4 = new Thread(new ThreadStart(delegate{
string[] count = GetContent("photo_count&id=" + a_id[n]);
string[] nik = GetContent("id2nik&id=" + a_idadd[n]);
newlabel6.Invoke(new MethodInvoker(delegate() { newlabel6.Text = "Город: " + Id2City(a_city[n] - 1) + "\nДобавил: " + nik[0]; }));
}));
trd4.Start();

Проблема в том, если предидущий поток не завершил свою работу, то новый поток его просто обрубает.
Как сделать так, чтобы при выполнение потока и при запуске следующего, предидущий выполнялся до конца.
PM MAIL   Вверх
Mutronics
Дата 11.7.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Что-то мне подсказывает, что проблема здесь с Invoke.
PM MAIL   Вверх
Mutronics
Дата 11.7.2007, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Помогите...
Ааааа...
PM MAIL   Вверх
mr.DUDA
Дата 11.7.2007, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

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



Юзайте оператор lock


--------------------
user posted image
PM MAIL WWW   Вверх
Mutronics
Дата 11.7.2007, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



mr.DUDA 
А можно инфу или пример, ничего по нему найти немогу.
PM MAIL   Вверх
mr.DUDA
Дата 11.7.2007, 21:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

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



Да легко: на любое действие, потенциально выполняемое в более чем одном потоке одновременно, ставится оператор lock, разрешающий вход только одному потоку в одно и то же время (второй поток терпеливо ожидает пока первый не выйдет из lock):
Код
void ПотокоНебезопасныйМетод()
{
     ...
    
     lock (здесь_ссылка_на_любой_объект)
     {
            ... внутри - код, который мы разрешаем выполнять лишь одному потоку в одно и то же время
     }

     ... 
}




--------------------
user posted image
PM MAIL WWW   Вверх
Mutronics
Дата 12.7.2007, 08:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Если это должно выглядеть так, то всеравно неработает !
Код

            object locker = new object();
            string[] count = GetContent("photo_count&id=" + a_id[n]);
            string[] nik = GetContent("id2nik&id=" + a_idadd[n]);
            lock (locker)
            {
                newlabel6.Invoke(new MethodInvoker(delegate()
                {
                    newlabel6.Text = "Город: " + Id2City(a_city[n] - 1) + "\nДобавил: " + nik[0];
                }));
            }

PM MAIL   Вверх
mr.DUDA
Дата 12.7.2007, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

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



locker должен быть не локальной переменной, а полем класса, лучше всего статическим:
Код
class A
{
      static object locker = new object();

      ...

      void Метод()
      {
            string[] count = GetContent("photo_count&id=" + a_id[n]);
            string[] nik = GetContent("id2nik&id=" + a_idadd[n]);
            newlabel6.Invoke(new MethodInvoker(delegate()
            {
                lock (locker)
                {
                    newlabel6.Text = "Город: " + Id2City(a_city[n] - 1) + "\nДобавил: " + nik[0];
                }      
            }));
      }
}


Иначе он создаётся каждый раз при входе в метод и теряется возможность блокировать одновременное выполнение нескольких потоков (в каждом потоке свой экземпляр locker-а). И помещать lock лучше не вокруг Invoke, а внутри - мало ли, захотим заменить на BeginInvoke...


--------------------
user posted image
PM MAIL WWW   Вверх
Mutronics
Дата 12.7.2007, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



mr.DUDA, И даже так неработает, всеравно предидущие потоки не завершаются при открытии новых
Код


static object locker = new object(); //в class frmMain

//это срабатывает при ТабКлик
trd4 = new Thread(new ThreadStart(test));
trd4.IsBackground = true;
trd4.Start();
//...

        void test()
        {
            string[] count = GetContent("photo_count&id=" + a_id[n]);
            string[] nik = GetContent("id2nik&id=" + a_idadd[n]);
            
                newlabel6.Invoke(new MethodInvoker(delegate()
                {
                     lock (locker)
                {

                    newlabel6.Text = "Город: " + Id2City(a_city[n] - 1) + "\nДобавил: " + nik[0];
                }   
                }));
        }

Могу выслать исходник, сам глянешь.

Это сообщение отредактировал(а) Mutronics - 12.7.2007, 09:47
PM MAIL   Вверх
mr.DUDA
Дата 12.7.2007, 09:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

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



Странно. Может их кто рубит (например Abort с последующим Join), или к примеру сами валятся с исключением... Можно попробовать поставить try..catch в методе test.


--------------------
user posted image
PM MAIL WWW   Вверх
tol05
Дата 12.7.2007, 09:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



оператор lock блокирует доступ к членам объекта.
Посторонний поток выполнения остановится только если он обращается в данный момент к этому объекту. Если посторонний поток (не тот, который лочит объект) выполняет в данный момент какую-то другую работу, то ему ничего не препятствует ее выполнять...

Цитата(Mutronics @  11.7.2007,  13:50 Найти цитируемый пост)
Как сделать так, чтобы при выполнение потока и при запуске следующего, предидущий выполнялся до конца.

Mutronics, посмотри в сторону AutoResetEvent или WaitHandle (WaitHandle.WaitOne() например)


--------------------
На хорошей работе и сны хорошие снятся.
PM MAIL   Вверх
mr.DUDA
Дата 12.7.2007, 10:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

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



Цитата(tol05 @  12.7.2007,  09:54 Найти цитируемый пост)
оператор lock блокирует доступ к членам объекта.

Неправильно. Оператор lock, дословно цитируя мсдн, выполняет следующее:

Цитата
The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock. This statement takes the following form:

Object thisLock = new Object();
lock (thisLock)
{
    // Critical code section
}
 
...

lock ensures that one thread does not enter a critical section of code while another thread is in the critical section. If another thread attempts to enter a locked code, it will wait, block, until the object is released.

Ни о каком блокировании членов объекта thisLock речи не идёт и идти не может.


Цитата(tol05 @  12.7.2007,  09:54 Найти цитируемый пост)
Mutronics, посмотри в сторону AutoResetEvent или WaitHandle (WaitHandle.WaitOne() например)

Между прочим, lock внутри себя также юзает объект синхронизации - Monitor (методы Enter, Leave).


--------------------
user posted image
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

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


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

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


 




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


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

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