I've been having trouble getting the below C# threading code to behave properly. I start a thread by clicking a button on a form, and the thread simply declares a float x
and increments it in a loop until threadRunning
is set to false. I set threadRunning
to false when I click the button again. When the loop completes, the thread sets threadResult
to the incremented value x
. I then display threadResult
on the form.
The problem is that threadResult
always gets set to 256.0 in this case. If I choose to increment x
by 0.0001f
, then threadResult
will always get set to 2048.0. These fixed values are assigned to threadResult
every time the thread runs.. unless I put a breakpoint on the incremented line, x += 0.00001f;
. This can be a conditional breakpoint with the condition set to false; as long as an enabled breakpoint exists on this line, x
is incremented properly and gets assigned to threadResult
.
---Edit 1---
To clarify what proper behavior is, which occurs only when an enabled breakpoint exists on the incremented line: threadResult
gets assigned a value equal to the number of times the incrementing line is hit multiplied by the increment value. So, if x
was incremented 121 times, and the increment value is 0.00001f, threadResult
should become 0.00121. This does occur when an enabled breakpoint exists on the incremented line and I'm running in debug mode.
Also, when I run this in release mode, the program hangs when I click the button to stop the thread, so I'm assuming something is wrong with my threading implementation entirely. I would still appreciate any pointers on what might be the problem with my code. I just wanted to write something to test stopping a thread. Also, I don't want to use BackgroundWorkers, because my threading code isn't intended to be used with Windows Forms. ---End Edit 1---
Can anyone explain to me what is going on here? Is the method that I use to stop the thread okay, by setting the thread's loop control variable to false outside of the thread? I've tried this code in Visual Studio 2017, 2015, and 2013, all with the same result.
Here is the code. The form contains only a button named button1
and a textbox named textBox1
.
using System;
using System.Windows.Forms;
using System.Threading;
namespace ThreadingTesting
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
button1.Click += Button1_Click;
}
private Thread thread;
private bool threadRunning = false;
private float threadResult = 0;
private void Button1_Click(object sender, EventArgs e)
{
if (threadRunning)
{
threadRunning = false;
thread.Join();
textBox1.Text = "Result: " + threadResult.ToString("N4");
button1.Text = "Start Thread";
}
else
{
thread = new Thread(new ThreadStart(ThreadedWork));
thread.Start();
textBox1.Text = "Thread Started!";
button1.Text = "Stop Thread";
}
}
private void ThreadedWork()
{
threadRunning = true;
float x = 0.0f;
while (threadRunning)
{
x += 0.00001f;
}
threadResult = x;
return;
}
}
}