2015-08-07 3 views
0

Я ищу ответ надолго, однако я не нашел ответа, как выглядит связь между потоками/основным потоком и потоками, созданными во время выполнения. У меня была эта проблема на Java, и теперь она возвращается на C#.Измените атрибуты основного класса из Thread

Предположим, что я хотел бы написать приложение C#, которое имеет форму с простым текстом Ярлык, и я хочу запустить thread (s), который увеличивает числовое значение, написанное на этой метке. Я создаю основной класс с формой и классом потока. то я создаю новый объект класса потока в моем основном классе и начинаю на нем поток.

Как изменить текст метки, которая определена в основном?

+0

Возможный дубликат http://stackoverflow.com/questions/661561/how-to-update-the-gui-from-another-thread-in-c?rq=1? –

+0

C# (в отличие от java) - это современный, правильно спроектированный язык программирования, который имеет языковые функции, которые облегчают запись асинхронного/потокового кода. Для получения дополнительной информации см. [Асинхронное программирование с использованием Async и Await (C# и Visual Basic)] (https://msdn.microsoft.com/en-us/library/hh191443.aspx) в MSDN. –

ответ

0

Итак, если вы правильно поняли, вы спрашиваете, как изменить графический интерфейс из другого потока.

Это делается через конструкцию, называемую SynchronizationContext, которая по существу обеспечивает способ запуска кода в другом потоке. Поэтому в вашем случае, если вы хотите изменить текст метки, определенной в потоке GUI, вы должны взять SynchronizationContext, соответствующий вашему потоку графического интерфейса пользователя, и отправить ему код через другой поток.

Другая концепция, с которой вам нужно познакомиться, - это Задачи. A Task - это абстракция, функционально то же, что и поток. Одновременно могут выполняться две задачи. Task.Run запускает новый Task с рабочей нагрузкой, представленной функцией.

С учетом сказанного, вот пример в WPF:

public class MainWindow 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     var context = SynchronizationContext.Current; 

     Task.Run(() => context.Post(state => Button.Content = "Hello World!")); 
    } 
} 

Обратите внимание, что даже если я внутри Task.Run (что означает, что я не на GUI потоке), я все еще в состоянии выполнить код на Button, разместив сообщение SynchroniztaionContext.


Edit: Если вы не знакомы с Task еще, и вы хотели бы использовать Thread вместо этого, вы можете быть в состоянии сделать это, а также:

var context = SynchronizationContext.Current; 

var thread = new Thread(() => context.Post(state => Button.Content = "Hello World!")); 

thread.Start(); 
+0

Значит, это означает, что невозможно запустить поток, который изменяет GUI? Это мне нужно? Насколько я понимаю, он меняет содержимое Button один раз. Я хотел бы сделать более сложную вещь. Например, вычислите что-то в потоке и индикатор прогресса. На данный момент я создал класс ресурсов, и я отправляю туда свои данные. – Niko

Смежные вопросы