1

I'm new to .net and i'm trying to apply two threads on one window

The application contains two buttons (start and stop) and one read only textbox when the user click on start the program will read from the com port and append it to the textbox and when click on stop it will stop. The problem is whenever i click on start the program stuck

only to make it shorter here i used "Hello World!".

C# code:

using System; using System.Windows; using System.Threading; namespace ThreadingTest { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private bool _continue = false; public MainWindow() { InitializeComponent(); } private void startWrite(object sender, RoutedEventArgs e) { startButton.IsEnabled = false; stopButton.IsEnabled = true; _continue = true; Dispatcher.Invoke((Action)(() => { Hello(); })); } private void stopWrite(object sender, RoutedEventArgs e) { startButton.IsEnabled = true; stopButton.IsEnabled = false; _continue = false; } public void Hello() { while (_continue) { HelloText.AppendText("Hello World!\n"); //_continue = false; } } } } 

xaml code:

<Window x:Class="ThreadingTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="296" Width="301" Background="WhiteSmoke"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="245*" /> <RowDefinition Height="12*" /> </Grid.RowDefinitions> <TextBox Name="HelloText" IsReadOnly="True" HorizontalAlignment="Left" Margin="12,12,0,0" VerticalAlignment="Top" Height="233" Width="174" /> <Button Name="startButton" IsEnabled="True" HorizontalAlignment="Left" VerticalAlignment="Top" Height="25" Width="50" Margin="208,12,0,0" Content="Start" Click="startWrite" /> <Button Name="stopButton" IsEnabled="False" HorizontalAlignment="Left" VerticalAlignment="Top" Height="25" Width="50" Margin="208,45,0,0" Content="Stop" Click="stopWrite" /> </Grid> </Window> 

and sorry for my English

5 Answers 5

1

You should use BackgroundWorker (msdn).

Example:

public partial class MainWindow : Window { private bool _continue = false; public MainWindow() { InitializeComponent(); worker.WorkerSupportsCancellation = true; worker.DoWork += delegate { Hello(); }; } BackgroundWorker worker = new BackgroundWorker(); private void startWrite(object sender, RoutedEventArgs e) { startButton.IsEnabled = false; stopButton.IsEnabled = true; _continue = true; worker.RunWorkerAsync(); } private void stopWrite(object sender, RoutedEventArgs e) { worker.CancelAsync(); startButton.IsEnabled = true; stopButton.IsEnabled = false; _continue = false; } public void Hello() { while (_continue) { Application.Current.Dispatcher.Invoke((Action)(() => { HelloText.AppendText("Hello World!\n"); })); } } } 
Sign up to request clarification or add additional context in comments.

1 Comment

almost works perfect, only i added Thread.sleep(100) in the end of the loop
0

Simple ... with
Dispatcher.Invoke((Action)(() => { Hello(); }));

you invoke this loop again back in the WPF Dispatcher Thread so you !Don't! use multithreding

My advice... inform yourself more about threads, callbacks and Tasks in C# at all and than start to use it in WPF

Comments

0

You don't need to "apply two threads on one window"...

You have your UI-Thread, and you need a second thread to get data from the com port and send it to your UI-Thread.

You can use for example the BackgroundWorker Class. And send the data via an additional event to the UI-Thread, where you catch the fired event and append the sent data to your textbox.

Comments

0

If you're going to perform any long running task which can be done in the background I suggest you take a look at the BackgroundWorker class.

Otherwise you might want to take a look at the Task and TaskFactory classes for less complex work (and code).

Comments

0

Here is the simplest approach:

private void startWrite(object sender, RoutedEventArgs e) { startButton.IsEnabled = false; stopButton.IsEnabled = true; _continue = true; Thread myThread = new Thread(startWriteThread); startWriteThread.Start(); } private void startWriteThread() { Hello(); } 

I do, however, recommend you to follow the recommendations as suggested by @Jurgen Camilleri, since it is a cleaner approach.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.