I need to stop a Thread when my timer is done.
But this all from a other function.
My Timer starts after Pressing Key: L. a Messagebox appears "Timer started" and my Thread starts too. after 10 seconds, Timer stops with message but my Thread is still running. What can i do? :/
void StartFunction()
{
Thread AB = new Thread(SEARCHING) { IsBackground = true };
AB.Start();
}
void StopFunction()
{
Thread AB = new Thread(SEARCHING);
AB.Abort();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.L)
{
StartFunction();
timer1.Start();
MessageBox.Show("Timer 1 started!");
}
}
int time = 0;
private void timer1_Tick(object sender, EventArgs e)
{
time ;
if (time == 10 && timer1.Enabled)
{
StopFunction();
MessageBox.Show("Timer 1 stoped!");
timer1.Stop();
time = 0;
}
}
CodePudding user response:
Idle_Mind is correct on how to accomplish this. Below is a working example using .NET 6.
One important detail is to use Thread.Join()
. This will tell your caller to block until the loop is exited and the method returns.
Here I use the command console to key off the switching of the _running
flag. You can do the same with a timer or whatever else. Keep in mind that you should probably also implement IDisposable
in your class with the thread in it and set _running
to false and do the join there as well. That way, you can instantiate the object with using
.
namespace Lala
{
class AB : IDisposable
{
private bool _running = false;
private readonly Thread _thread;
public AB() => _thread = new Thread(Method);
private void Method()
{
while (_running)
{
Console.WriteLine("doing stuff");
Thread.Sleep(1000);
}
}
public void StartMethod()
{
_running = true;
_thread.Start();
}
public void StopMethod()
{
_running = false;
_thread.Join();
}
public void Dispose() => StopMethod();
}
public class Program
{
public static void Main()
{
Console.WriteLine("Launching a Thread. Press any key to stop it");
using AB ab = new();
// AB ab = new(); // if using is not appropriate
ab.StartMethod();
while (!Console.KeyAvailable)
Thread.Sleep(10);
// ab.StopMethod();// if using is not appropriate
}
}
}
CodePudding user response:
Using modern methods you would write something like
private async void Form1_KeyDown(object sender, KeyEventArgs e)
{
var cts = new CancellationTokenSource(10000);
var task = Task.Run(() => Search(cts.Token));
try
{
var result = await task;
// handle result
}
catch (OperationCanceledException)
{
// handle cancelled
}
catch (Exception)
{
// handle other exceptions
}
}
public int Search(CancellationToken cancel)
{
while (true)
{
cancel.ThrowIfCancellationRequested();
// Do searching
if (found)
return result;
}
}
This would use thread pool threads instead of dedicated threads, and avoids the need to manually managing a timer. It also makes it easy to handle the result from the operation, if there are any.