9 / 9 / 6
Регистрация: 09.05.2015
Сообщений: 524
1

Недопустимая операция в нескольких потоках

03.01.2018, 02:01. Показов 1549. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
1. Есть класс MyClass в котором метод MyMethod каждую секунду увеличевает переменную на a 1 и TestEvent - событие которое срабатывает через каждую секунду и передаеет в своем аргументе значение переменной а
2. Создаю экземпляр класса и вызываю его метод в новом потоке, также создаю его событие которому назначаю мутод в котором пишу progressBar1.Value = progress;
и у меня выбивает ошибка

я понял что сообщенный метод с TestEvent - пренадлежит вторичном потоку (хотя вроде бы находится в первичном на первый взгляд). Я со вторичного потока обращаюсь к элементу progressBar1 который относится к первичному. Вот и ошибка. А Как мне быть? Помогите пожалуйста.
Как сделать что бы прогрессБар получал значения с вторичного потока и отображал его. Его как то надо добавить в контекст Вторичного потока?
Миниатюры
Недопустимая операция в нескольких потоках  
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.01.2018, 02:01
Ответы с готовыми решениями:

Недопустимая операция в нескольких потоках
private void url_button_Click(object sender, EventArgs e) { textarea.Text =...

Недопустимая операция в нескольких потоках
Приветствую! Задался задачей реализовать подобный пример на WinForms, заменив консоль textBox'ом...

Недопустимая операция в нескольких потоках
Вроде всё правильно

Недопустимая операция в нескольких потоках
Коллеги, добрый день! Вот кусочек кода: private void backgroundWorker1_DoWork(object...

13
9 / 9 / 6
Регистрация: 09.05.2015
Сообщений: 524
03.01.2018, 02:35  [ТС] 2
Код программы

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
 
namespace WindowsFormsApp8
{
    delegate void DEligate(int progress);
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            MyClass TestClass = new MyClass();
            TestClass.TestEvent += TestClass_TestEvent;
 
            Thread POTOK = new Thread(TestClass.MyMethod);
            POTOK.IsBackground = true;
            POTOK.Start();
        }
 
        private void TestClass_TestEvent(int progress)
        {
            progressBar1.Value = progress;
             
        }
    }
 
    class MyClass
    {
        public event DEligate TestEvent;
        static int a = 0;
        public void MyMethod()
        {
            while (true)
            {
                a = a + 1;
                TestEvent.Invoke(a);
                Thread.Sleep(1000);
            }
        }
    }
 
}
0
1216 / 1004 / 259
Регистрация: 15.06.2012
Сообщений: 3,888
03.01.2018, 02:52 3
https://msdn.microsoft.com/ru-... .110).aspx
https://msdn.microsoft.com/ru-... .110).aspx

C#
1
2
3
4
5
private void TestClass_TestEvent(int progress)
        {
            progressBar1.BeginInvoke(() => progressBar1.Value = progress);
             
        }
0
9 / 9 / 6
Регистрация: 09.05.2015
Сообщений: 524
03.01.2018, 21:26  [ТС] 4
немогу устранить ошибку. игразся с точкой и запятой, так и непонял куда ее тулить
0
9 / 9 / 6
Регистрация: 09.05.2015
Сообщений: 524
03.01.2018, 21:30  [ТС] 5
Недопустимая операция в нескольких потоках


немогу устранить ошибку. игразся с точкой и запятой, так и непонял куда ее тулить
0
1147 / 739 / 483
Регистрация: 21.01.2014
Сообщений: 1,903
03.01.2018, 23:39 6
Sayanchik777,
C#
1
2
3
4
private void TestClass_TestEvent(int progress)
{
    progressBar1.BeginInvoke(new Action(() => progressBar1.Value = progress));
}
P.S. Выкладывайте код текстом с тегами, а не скриншотом.
1
9 / 9 / 6
Регистрация: 09.05.2015
Сообщений: 524
04.01.2018, 00:28  [ТС] 7
Получается хоть и тело метода TestClass_TestEvent находится в в основному потеке- оно пренадлежит вторичном потоку. С вторичного потока нет доступа к прогресбару.progressBar1.BeginInvoke - второй поток говорит первому запусти прогрес с значением progress?

Добавлено через 1 минуту
private void TestClass_TestEvent(int progress)
{

Переменная int какому потоку пренадлежит?
0
Эксперт .NET
9768 / 5941 / 1401
Регистрация: 25.05.2015
Сообщений: 18,097
Записей в блоге: 14
04.01.2018, 12:09 8
Лучший ответ Сообщение было отмечено Sayanchik777 как решение

Решение

Цитата Сообщение от Sayanchik777 Посмотреть сообщение
Получается хоть и тело метода TestClass_TestEvent находится в в основному потеке- оно пренадлежит вторичном потоку.
Нет. Главное - из какого потока вызывается метод, в том он и выполняется.
Цитата Сообщение от Sayanchik777 Посмотреть сообщение
С вторичного потока нет доступа к прогресбару.
Доступ есть, но контролы не приспособлены к такой работе, когда их методы вызываются из разных потоков. Программа упадёт.
Цитата Сообщение от Sayanchik777 Посмотреть сообщение
progressBar1.BeginInvoke - второй поток говорит первому запусти прогрес с значением progress?
Делегат метода передаётся в очередь сообщений, в которой работает указываемый контрол, и оттуда вызывается (как очередь до него дойдёт).
Непродуманное применение такого способа может легко привести к переполнению очереди ненужными сообщениями. Что приведёт к постепенному торможению программы, а то и к падению, если указываемый контрол к моменту выполнения делегата уже будет уничтожен.
Цитата Сообщение от Sayanchik777 Посмотреть сообщение
Переменная int какому потоку пренадлежит?
Ни к какому.
1
9 / 9 / 6
Регистрация: 09.05.2015
Сообщений: 524
04.01.2018, 18:40  [ТС] 9
Цитата Сообщение от Rius Посмотреть сообщение
Непродуманное применение такого способа может легко привести к переполнению очереди ненужными сообщениями.
Безопасние выполнять в первом потоке какойто метод, тело которого будет переприсваевать значение прогрем бару (таймером например). это будет более безопастние?
0
1216 / 1004 / 259
Регистрация: 15.06.2012
Сообщений: 3,888
04.01.2018, 19:44 10
Sayanchik777, в WinForms есть TimerControl, который уже выполняет действия в нужном потоке.

Rius, чисто проорать -- а как разруливается MVVM с разными потоками?
0
Эксперт .NET
9768 / 5941 / 1401
Регистрация: 25.05.2015
Сообщений: 18,097
Записей в блоге: 14
04.01.2018, 20:41 11
Цитата Сообщение от Sayanchik777 Посмотреть сообщение
Безопасние выполнять в первом потоке какойто метод, тело которого будет переприсваевать значение прогрем бару (таймером например). это будет более безопастние?
Да, но так не делается. Лучше просто не засорять очередь.

Wolfdp, что за MVVM? В WPF? Та же проблема - UI может работать только из одного потока.
0
1216 / 1004 / 259
Регистрация: 15.06.2012
Сообщений: 3,888
04.01.2018, 20:59 12
Rius,
я малость не про то:
- создаем модель, реализуем интерфейс IChangeProperty ( или как его там)
- привязываем значение поля к значению контрола.
- меняем значение модели в другом потоке.

Лично у меня без инвоков завалилось (окей, понятно), но появляется вопрос -- как адекватно разрешить вопрос привязки? Получается либо модель должна знать в каком потоке бросать ивент, либо мы контролировать действия с моделью в правильном потоке.
0
Эксперт .NET
9768 / 5941 / 1401
Регистрация: 25.05.2015
Сообщений: 18,097
Записей в блоге: 14
04.01.2018, 21:30 13
Wolfdp, можно внутри ViewModel ловить события от Model и синхронизировать их с потоком UI.
Model тогда знать не будет, и View тоже не будет.
0
TheGreatCornholio
1249 / 727 / 285
Регистрация: 30.07.2015
Сообщений: 2,403
04.01.2018, 21:59 14
Если лениво совсем, можно так попробовать.
https://msdn.microsoft.com/ru-... .110).aspx
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.01.2018, 21:59
Помогаю со студенческими работами здесь

Недопустимая операция в нескольких потоках
Код: using System; using System.Collections.Generic; using System.ComponentModel; using...

Недопустимая операция в нескольких потоках
Доброго времени суток. Вот код. void StartAll () { Thread.Sleep(2000); ...

Асинхронные потоки. Недопустимая операция в нескольких потоках
Здравствуйте, Я использую асинхронные потоки. Объясните пожалуйста (не гоните стразу читать...

Доступ к ProgressBar. Недопустимая операция в нескольких потоках
Здравствуйте! Есть проблема. В форме создаю новый поток и в нем пытаюсь изменить любое свойство...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru