Привет, подскажите как узнать жив ли поток ещё 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(); } } Нужно чтобы после выполнения внутреннего цикла подождать чтобы все потоки запущенные во внутреннем цикле завершились
Самое простое. Веди счетчик потоков. Когда создаешь увеличивай. Когда поток завершается в нем отнимай. Не забудь про синхронизацию.
Я бы рекомендовал использовать класс Task, заместо Thread. А для ожидания завершения всех потоков, статический метод из Task: Code: public static void WaitAll( params Task[] tasks )
Да пздц ваще. 1 вариант: пишешь свою обертку над Thread, где добавляешь событие ThreadTerminated (20-30 строк кода, максимум полчаса) 2 вариант: хранишь ссылки на потоки в коллекции, поток в начале работы добавляется в коллекцию, по окончании удаляется из нее. Коллекция имеет события CollectionChanged. Такое реализовать вообще 20 минут, а с решарпером вообще 10. Теперь вопрос на засыпку: новоявленные шарпо-быдлокодеры вообще не понимают событийно-ориентированное программирование?
Тогда следующий вопросы Поток живет с момента Start() и до того как он выполнит переданный ему метод? Почему метод IsAlive все время возвращаяет 1 ? Не чего страшного что у меня в цикле все работают с 1 экземпляром thread?
уточнение Метод который вызывается потоком 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; } }
PHP: System.Collections.ObjectModel.ObservableCollection<string> a = new ObservableCollection<string>(); public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { a.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(a_CollectionChanged); } void a_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) { MessageBox.Show("lol"); } private void button1_Click(object sender, EventArgs e) { a.Add("1"); } жаль только что только под NET 4.0
Да. Даже не знаю. Я вообще не так отслеживаю состояние потоков. Да и тип свойства 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); } // и так для всех нужных методов } Надеюсь, комментарии по коду излишни?
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 если можно дай свою асю в пм, а то так жутко не удобно общаться
Ну да, ничего страшного, будет запущено столько потоков сколько надо. Но переменная 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(); Аську сейчас в профиле укажу, но если ты не различаешь класс и объект то лучше не стучи даже
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
Abort это метод Thread вообще-то О да, он для того и предназначен чтобы немедленно прервать поток. Когда нужно остановить сотню потоков из длительной операции лучшую альтернативу не найти. А еще не нашел где он там не рекомендуется. Написано что могут быть проблемы в определенных сценариях, ну так эти проблемы надо обходить, а не знающий человек пишущий код сам по себе опасен, даже без вызовов Abort И он не [Obsolete] А Join уже из другой оперы. Делегирование имхо в этом случае неуместно, хотя кому как удобнее.