[C#] Определение жизни потока

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by vavilrus, 9 Jun 2011.

  1. vavilrus

    vavilrus New Member

    Joined:
    19 Mar 2008
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    Привет, подскажите как узнать жив ли поток ещё

    Code:
                        for (int i = 0; i < count_iteration; i++)
                        {
                            for (int j = 0; j < count_code_for_iteration; j++)
                            {
                                thread = new Thread(debug);
                                thread.Name = "thread" + j;
                                thread.Start();
                            }
                        }
    Нужно чтобы после выполнения внутреннего цикла подождать чтобы все потоки запущенные во внутреннем цикле завершились
     
  2. St0nX

    St0nX Elder - Старейшина

    Joined:
    19 May 2007
    Messages:
    257
    Likes Received:
    46
    Reputations:
    0
    Самое простое. Веди счетчик потоков. Когда создаешь увеличивай. Когда поток завершается в нем отнимай. Не забудь про синхронизацию.
     
  3. X-rus

    X-rus Member

    Joined:
    22 Dec 2010
    Messages:
    88
    Likes Received:
    22
    Reputations:
    4
    Я бы рекомендовал использовать класс Task, заместо Thread.

    А для ожидания завершения всех потоков, статический метод из Task:
    Code:
    public static void WaitAll(
    	params Task[] tasks
    )
     
  4. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Да пздц ваще.
    1 вариант:
    пишешь свою обертку над Thread, где добавляешь событие ThreadTerminated (20-30 строк кода, максимум полчаса)
    2 вариант: хранишь ссылки на потоки в коллекции, поток в начале работы добавляется в коллекцию, по окончании удаляется из нее. Коллекция имеет события CollectionChanged. Такое реализовать вообще 20 минут, а с решарпером вообще 10.
    Теперь вопрос на засыпку: новоявленные шарпо-быдлокодеры вообще не понимают событийно-ориентированное программирование?
     
  5. vavilrus

    vavilrus New Member

    Joined:
    19 Mar 2008
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    Тогда следующий вопросы

    Поток живет с момента Start() и до того как он выполнит переданный ему метод?
    Почему метод IsAlive все время возвращаяет 1 ?
    Не чего страшного что у меня в цикле все работают с 1 экземпляром thread?
     
  6. vavilrus

    vavilrus New Member

    Joined:
    19 Mar 2008
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0
    уточнение

    Метод который вызывается потоком
    Code:
            private void debug()
            {
                count_thread++;
                SetTextforDebag(Thread.CurrentThread.Name);
                count_thread--;
            }
    метод SetTextforDebag

    Code:
    private void SetTextforDebag(string s)
            {
                if (tb_debug.InvokeRequired)
                {
                    SetTextDebug settext = new SetTextDebug(SetTextforDebag);
                    this.Invoke(settext, new object[] { s });
                }
                else
                {
                    tb_debug.Text += s + Environment.NewLine; 
                }
            }
     
  7. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    а на NF2.0 есть что-то похожее ?
     
  8. ShkiperLol

    ShkiperLol Banned

    Joined:
    17 Apr 2010
    Messages:
    182
    Likes Received:
    1
    Reputations:
    0
    PHP:
    System.Collections.ObjectModel.ObservableCollection<string= new ObservableCollection<string>();
            public 
    Form1()
            {
                
    InitializeComponent();
            }

            private 
    void Form1_Load(object senderEventArgs e)
            {
                
    a.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(a_CollectionChanged);
            }

            
    void a_CollectionChanged(object senderSystem.Collections.Specialized.NotifyCollectionChangedEventArgs e)
            {
                
    MessageBox.Show("lol");
            }

            private 
    void button1_Click(object senderEventArgs e)
            {
                
    a.Add("1");
            }
    жаль только что только под NET 4.0 :(
     
    #8 ShkiperLol, 9 Jun 2011
    Last edited: 9 Jun 2011
  9. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Да.
    Даже не знаю. Я вообще не так отслеживаю состояние потоков. Да и тип свойства bool причем здесь 1?
    Даже не понял этот вопрос.
    Сколько потоков надо столько и объектов создаешь.
    Проще всего хранить в коллекциях, например:
    List<Thread> threads = new List<Thread>();
    threads.Add(new Thread( () => Console.WriteLine(42) ) );
    Кстати если эти переменные общие для всех потоков то правильней юзать Interlocked:
    count_thread = Interlocked.Increment(ref count_thread);

    Набросал прям в браузере:

    Code:
    public enum Operation {Added, Removed, Changed}
    
    public class ListEx<T> : List<T>
    {
      // собственно событие
      // передается объект вызвавший, элемент и вид операции над элементом
      public event Action<ListEx<T>, Operation, T> CollectionChanged;
    
      public new void Add(T arg)
      {
         base.Add(arg);
         if (CollectionChanged != null)
             CollectionChanged(this, Operation.Added, arg);
      }
      
      // и так для всех нужных методов
    }
    Надеюсь, комментарии по коду излишни?
     
  10. vavilrus

    vavilrus New Member

    Joined:
    19 Mar 2008
    Messages:
    0
    Likes Received:
    0
    Reputations:
    0

    Code:
     for (int j = 0; j < count_code_for_iteration; j++)
                            {
                                thread = new Thread(debug);
                                thread.Name = "thread" + j;
                                thread.Start();
                            }
    thread объявлена ранее, и меня интересует не чего страшного что я эксплуатирую этот thread при каждой итерации цикла?



    И не совсем понял конструцию
    Code:
     threads.Add(new Thread( () => Console.WriteLine(42) ) )
    мы в список добавляем новый экземпляр класса, но иммя ему не задаём?

    GhostOnline если можно дай свою асю в пм, а то так жутко не удобно общаться
     
  11. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Ну да, ничего страшного, будет запущено столько потоков сколько надо. Но переменная thread так "затирается", и на созданные потоки ты уже не имеешь ссылок.
    Тогда уж можно и так:
    Code:
    for (int i = 0; i < count_code_for_iteration; i++)
      new Thread(debug){Name = "thread" + i}.Start();
    как бы получится тоже самое, но без лишней переменной, более наглядно и меньше кода.
    А зачем переменная/имя? Тем более что ты как в коде выше все равно ее затираешь. Ссылка сохраняется в списке List<Thread>, к конкретному потоку можно обратиться через индексатор:
    Code:
    threads[66].Abort();
    а остановить все потоки можно так:
    Code:
    foreach(vat thread in threads)
      thread.Abort();
    Аську сейчас в профиле укажу, но если ты не различаешь класс и объект то лучше не стучи даже :)
     
    #11 GhostOnline, 9 Jun 2011
    Last edited: 9 Jun 2011
  12. W!z@rD

    W!z@rD Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    290
    Reputations:
    43
    Abort для Thread?
    О дааа...

    http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx
    советую прочитать, в двух словах, давно не рекомендуется вызывать Abort.

    читаем про Join.

    http://msdn.microsoft.com/en-us/library/system.threading.thread.threadstate.aspx
    это смотри.


    Shkiper ObservableCollection тут не нужен.

    Создается класс и:
    1. наследуется от IList
    2. создается private объект-коллекция, public методы AddItem, RemoveItem
     
  13. GhostOnline

    GhostOnline Active Member

    Joined:
    20 Dec 2008
    Messages:
    723
    Likes Received:
    110
    Reputations:
    22
    Abort это метод Thread вообще-то :D
    О да, он для того и предназначен чтобы немедленно прервать поток.
    Когда нужно остановить сотню потоков из длительной операции лучшую альтернативу не найти.
    А еще не нашел где он там не рекомендуется. Написано что могут быть проблемы в определенных сценариях, ну так эти проблемы надо обходить, а не знающий человек пишущий код сам по себе опасен, даже без вызовов Abort :)
    И он не [Obsolete]
    А Join уже из другой оперы.
    Делегирование имхо в этом случае неуместно, хотя кому как удобнее.
     
    #13 GhostOnline, 10 Jun 2011
    Last edited: 10 Jun 2011