islem = new Thread(new ThreadStart(ilk));
islem2 = new Thread(new ThreadStart(ikinci));
islem3 = new Thread(new ThreadStart(ucuncu));
islem4 = new Thread(new ThreadStart(dorduncu));
islem.Start();
islem2.Start();
islem3.Start();
islem4.Start();
if (!islem.IsAlive)
{
islem2.Suspend();
islem3.Suspend();
islem4.Suspend();
}
I want to do when islem is done. Other threads suspend but it doesn't work
I read about ManualResetEvent but I can't figure out multi-threading examples.They works just one thread simples. Also I read http://www.albahari.com/threading/part4.aspx#_Suspending_and_Resuming this paper to and look similar questions like C# controlling threads (resume/suspend) How to pause/suspend a thread then continue it? Pause/Resume thread whith AutoResetEvent I am working multi - thread objects
If you just need to cancel the worker threads, the very simplest approach is to use a flag. You have to mark the flag volatile to ensure all threads are using the same copy.
private volatile bool _done = false;
void Main()
{
StartWorkerThreads();
}
void WorkerThread()
{
while (true)
{
if (_done) return; //Someone else solved the problem, so exit.
ContinueSolvingTheProblem();
}
_done = true; //Tell everyone else to stop working.
}
If you truly want to pause (I'm not sure why) you can use a ManualResetEvent. This allows blocking behavior without consuming resources for the paused thread.
//When signalled, indicates threads can proceed.
//When reset, threads should pause as soon as possible.
//Constructor argument = true so it is set by default
private ManualResetEvent _go = new ManualResetEvent(true);
void Main()
{
StartWorkerThreads();
}
void WorkerThread()
{
while (true)
{
_go.WaitOne(); //Pause if the go event has been reset
ContinueSolvingTheProblem();
}
_go.Reset(); //Reset the go event in order to pause the other threads
}
You can also combine the approaches, e.g. if you wanted to be able to pause the threads, do some more work, then cancel them:
private volatile bool _done = false;
private ManualResetEvent _go = new ManualResetEvent(true);
void Main()
{
StartWorkerThreads();
}
void WorkerThread()
{
while (true)
{
if (_done) return; //Exit if problem has been solved
_go.WaitOne(); //Pause if the go event has been reset
if (_done) return; //Exit if problem was solved while we were waiting
ContinueSolvingTheProblem();
}
_go.Reset(); //Reset the go event in order to pause the other threads
if (VerifyAnswer())
{
_done = true; //Set the done flag to indicate all threads should exit
}
else
{
_go.Set(); //Tell other threads to continue
}
}
Related
I'm developing a project on Visual Studio 2015 using C# and WPF. Sometimes I quit my running project with my close command, and sometimes with the stop debug button. The problem is that after a few tests, my PC starts to warm and the fans make noise. I have to quit Visual Studio to calm the machine.
So I have questions :
How to see the threads not ended after a test ?
When I know them, how to properly end them ? (actually I Dispose some threads when WindowClosing)
How make sure that thread will properly ends when I use the stop debug button ?
Thank you
EDIT:
There is the screenshot of task manager. When I start application the CPU rise from 5% to 15% (or event 25%). RAM rise from 4GO to 4.5.
When I stop application, CPU goes to 45% for a few seconds and go back to 5% but RAM goes to 4.70GO and doesn't go back down.
EDIT2:
I founded this kind of thread on my application:
private bool isClosing = false;
public void Start()
{
isClosing = false;
ThreadPool.QueueUserWorkItem(new WaitCallback(doWorkThread));
}
public void Stop()
{
isClosing = true;
}
private AutoResetEvent endPoolStateButton = new AutoResetEvent(false);
private void doWorkThread(object sender)
{
Action action = new Action(() => doWork());
while (!isClosing)
{
Thread.Sleep(100);
this.Dispatcher.BeginInvoke(action, System.Windows.Threading.DispatcherPriority.Background);
}
endPoolStateButton.Set();
}
private void doWork()
{
/* Job performed */
}
I wonder if there is a really good way to use thread ? If application close without setting isClosing = true the while never stop. And the thread is never really aborted ? Do you think that this kind of thread can cause all the troubles I have ?
Here is my solution how to stop thread in elegant way. Hope the code is clear. I use CancellationToken to cancel operations in thread and ManualResetEvent to wait for thread cancellation:
namespace ElegantThreadWork
{
using System;
using System.Threading;
using System.Diagnostics;
class ThreadObject
{
public CancellationToken CancellationToken { get; private set; }
public ManualResetEvent WaitHandle { get; private set; }
public ThreadObject(CancellationToken ct, ManualResetEvent wh)
{
CancellationToken = ct;
WaitHandle = wh;
}
}
public class Program
{
static void DoWork(CancellationToken ct)
{
Console.WriteLine("Thread[{0}] started", Thread.CurrentThread.ManagedThreadId);
int i = 0;
// Check for cancellation on each iteration
while (!ct.IsCancellationRequested)
{
// Do something
Console.WriteLine("Thread[{0}]: {1}", Thread.CurrentThread.ManagedThreadId, i);
// Wait on CancellationToken. If cancel be called, WaitOne() will immediatly return control!
// You can see it by elapsed time
ct.WaitHandle.WaitOne(TimeSpan.FromSeconds(1));
i++;
}
Console.WriteLine("Thread[{0}] has been cancelled", Thread.CurrentThread.ManagedThreadId);
}
static void ThreadProc(object state)
{
ThreadObject to = (ThreadObject)state;
try
{
DoWork(to.CancellationToken);
}
finally
{
to.WaitHandle.Set();
}
}
public static void Main(string[] args)
{
TimeSpan MAX_THREAD_EXITING_TIMEOUT = TimeSpan.FromSeconds(5);
// Use for elegant thread exiting
ManualResetEvent isThreadExitedEvent = new ManualResetEvent(false);
CancellationTokenSource cts = new CancellationTokenSource();
ThreadObject threadObj = new ThreadObject(cts.Token, isThreadExitedEvent);
// Create thread
Thread thread = new Thread(ThreadProc, 0);
thread.Start(threadObj);
Console.WriteLine("Just do something in main thread");
Console.WriteLine("Bla.");
Thread.Sleep(1000);
Console.WriteLine("Bla..");
Thread.Sleep(1000);
Console.WriteLine("Bla...");
Thread.Sleep(1000);
Console.WriteLine("Thread cancelattion...");
Stopwatch sw = Stopwatch.StartNew();
// Cancel thread
cts.Cancel();
// Wait for thread exiting
var isOk = isThreadExitedEvent.WaitOne(MAX_THREAD_EXITING_TIMEOUT);
sw.Stop();
Console.WriteLine("Waiting {0} for thread exiting. Wait result: {1}. Cancelled in {2}", MAX_THREAD_EXITING_TIMEOUT, isOk, sw.Elapsed);
// If we couldn't stop thread in elegant way, just abort it
if (!isOk)
thread.Abort();
}
}
}
Maybe you can try to observe the behaviour of the process and the threads with the tool "Process Hacker". With this tool you get more detailed informations about the thread and you also can detect deamon threads.
Another way could be: Try to get all child threads of the main process and do something like
Thread t1; // specific child thread
t1.join();
How can I pause/resume a thread? Once I Join() a thread, I can't restart it.
So how can I start a thread and make it pause whenever the button 'pause' is pressed, and resume it when resume button is pressed?
The only thing this thread does, is show some random text in a label control.
Maybe the ManualResetEvent is a good choice.
A short example:
private static EventWaitHandle waitHandle = new ManualResetEvent(initialState: true);
// Main thread
public void OnPauseClick(...) {
waitHandle.Reset();
}
public void OnResumeClick(...) {
waitHandle.Set();
}
// Worker thread
public void DoSth() {
while (true) {
// show some random text in a label control (btw. you have to
// dispatch the action onto the main thread)
waitHandle.WaitOne(); // waits for the signal to be set
}
}
I could suggest you to read Threading in C#, by Joe Albahari, particularly Suspend and Resume section:
A thread can be explicitly suspended and resumed via the deprecated methods Thread.Suspend and Thread.Resume. This mechanism is completely separate to that of blocking. Both systems are independent and operate in parallel.
A thread can suspend itself or another thread. Calling Suspend results in the thread briefly entering the SuspendRequested state, then upon reaching a point safe for garbage collection, it enters the Suspended state. From there, it can be resumed only via another thread that calls its Resume method. Resume will work only on a suspended thread, not a blocked thread.
From .NET 2.0, Suspend and Resume have been deprecated, their use discouraged because of the danger inherent in arbitrarily suspending another thread. If a thread holding a lock on a critical resource is suspended, the whole application (or computer) can deadlock. This is far more dangerous than calling Abort — which results in any such locks being released (at least theoretically) by virtue of code in finally blocks.
It's not the best idea to manually suspend and resume threads. However, you can easily simulate this behavior by using thread synchronization primitives (like ManualResetEvent)
Take a look at this question, you may find it helpful.
But I believe you can easily achieve your goal of 'showing random text in a label control' on a time basis by using timers.
Here is a quick example using DispatcherTimer
var timer = new DispatcherTimer();
timer.Tick += (s, e) => Label.Text = GetRandomText();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Start();
You can pause it by calling timer.Stop() and then timer.Start() again to resume.
Here's two ways that's worked for me. Both assume that the worker thread has it's own processing loop.
Have the thread invoke a callback to request permission to keep going
Have the parent invoke a method on the thread's class to signal it
The console application example below shows both approaches, using a callback to pause/continue, and a worker method to stop. Another advantage of the callback method is that it's also convenient for passing back status updates while it's checking for permission to continue.
using System;
using System.Threading;
namespace ConsoleApplication7
{
class Program
{
static bool keepGoing;
static void Main(string[] args)
{
keepGoing = true;
Worker worker = new Worker(new KeepGoingDelegate(KeepGoing));
Thread thread = new Thread(worker.DoWork);
thread.IsBackground = true;
thread.Start();
while (thread.ThreadState != ThreadState.Stopped)
{
switch (Console.ReadKey(true).KeyChar)
{
case 'p':
keepGoing = false;
break;
case 'w':
keepGoing = true;
break;
case 's':
worker.Stop();
break;
}
Thread.Sleep(100);
}
Console.WriteLine("Done");
Console.ReadKey();
}
static bool KeepGoing()
{
return keepGoing;
}
}
public delegate bool KeepGoingDelegate();
public class Worker
{
bool stop = false;
KeepGoingDelegate KeepGoingCallback;
public Worker(KeepGoingDelegate callbackArg)
{
KeepGoingCallback = callbackArg;
}
public void DoWork()
{
while (!stop)
{
Console.Write(KeepGoingCallback()?"\rWorking":"\rPaused ");
Thread.Sleep(100);
}
Console.WriteLine("\nStopped");
}
public void Stop()
{
stop = true;
}
}
}
I have a problem with C# threads.
I have eendless process “worker”, which do some and after iteration sleep 3 seconds.
I have a timer function that runs at a given time.
I need the "timer function" do something, then wait for the end "worker" iteration and then pause "worker" until "timer function" is done own task , after that timer function starts a "worker" again.
How can I do that?
Best regards Paul
You could use wait handles to control the methods - something like:
private AutoResetEvent mWorkerHandle = new AutoResetEvent(initialState: false);
private AutoResetEvent mTimerHandle = new AutoResetEvent(initialState: false);
// ... Inside method that initializes the threads
{
Thread workerThread = new Thread(new ThreadStart(Worker_DoWork));
Thread timerThread = new Thread(new ThreadStart(Timer_DoWork));
workerThread.Start();
timerThread.Start();
// Signal the timer to execute
mTimerHandle.Set();
}
// ... Example thread methods
private void Worker_DoWork()
{
while (true)
{
// Wait until we are signalled
mWorkerHandle.WaitOne();
// ... Perform execution ...
// Signal the timer
mTimerHandle.Set();
}
}
private void Timer_DoWork()
{
// Signal the worker to do something
mWorkerHandle.Set();
// Wait until we get signalled
mTimerHandle.WaitOne();
// ... Work has finished, do something ...
}
This should give you an idea of how to control methods running on other threads by way of a WaitHandle (in this case, an AutoResetEvent).
You can use a lock to pause a thread while another is doing something:
readonly object gate = new object();
void Timer()
{
// do something
...
// wait for the end "worker" iteration and then
// pause "worker" until "timer function" is done
lock (gate)
{
// do something more
...
}
// start the "worker" again
}
void Worker()
{
while (true)
{
lock (gate)
{
// do something
...
}
Thread.Sleep(3000);
}
}
Do you need paralel work of Worker and another operation? If not, You can do somthing similar:
EventWaitHandle processAnotherOperationOnNextIteration = new EventWaitHandle(false, EventResetMode.ManualReset);
Worker()
{
while(true)
{
doLongOperation();
if (processAnotherOperationOnNextIteration.WaitOne(0))
{
processAnotherOperationOnNextIteration.Reset();
doAnotherOperation();
}
Thread.Sleep(3000);
}
}
in timer
void Timer()
{
processAnotherOperationOnNextIteration.Set();
}
Problem statement
I have a worker thread that basically scans a folder, going into the files within it, and then sleeps for a while. The scanning operation might take 2-3 seconds but not much more. I'm looking for a way to stop this thread elegantly.
Clarification: I want to stop the thread while it's sleeping, and not while it's scanning. However, the problem is that I do not know what is the current state of the thread. If it's sleeping I want it to exit immediately. If it's scanning, I want it to exit the moment it tries to block.
Attempts at a solution
At first I was using Sleep and Interrupt. Then I found out that Interrupt doesn't really interrupt the Sleep - it only works when the threads TRIES to go into sleeping.
So I switched to Monitor Wait&Pulse. Then I found out that the Pulse only works when I'm actually in the Wait. So now I have a thread which looks like that:
while (m_shouldRun)
{
try
{
DoSomethingThatTakesSeveralSeconds();
lock (this)
{
Monitor.Wait(this, 5000);
}
}
catch (ThreadInterruptedException)
{
m_shouldRun = false;
}
}
And now I need to craft my Stop function. So I started with:
public void Stop()
{
m_shouldRun = false;
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
But this doesn't work because I may be pulsing while the thread works (while it's not waiting). So I added Interrupt:
public void Stop()
{
m_shouldRun = false;
thread.Interrupt();
lock (this)
{
Monitor.Pulse(this);
}
thread.Join();
}
Another option is to use:
public void Stop()
{
m_shouldRun = false;
while (!thread.Join(1000))
{
lock (this)
{
Monitor.Pulse(this);
}
}
}
The question
What is the preferred method? Is there a third method which is preferable?
Another alternative is to use events:
private ManualResetEvent _event = new ManualResetEvent(false);
public void Run()
{
while (true)
{
DoSomethingThatTakesSeveralSeconds();
if (_event.WaitOne(timeout))
break;
}
}
public void Stop()
{
_event.Set();
thread.Join();
}
The way to stop a thread elegantly is to leave it finish by itself. So inside the worker method you could have a boolean variable which will check whether we want to interrupt. By default it will be set to false and when you set it to true from the main thread it will simply stop the scanning operation by breaking from the processing loop.
I recommend to keep it simple:
while (m_shouldRun)
{
DoSomethingThatTakesSeveralSeconds();
for (int i = 0; i < 5; i++) // example: 5 seconds sleep
{
if (!m_shouldRun)
break;
Thread.Sleep(1000);
}
}
public void Stop()
{
m_shouldRun = false;
// maybe thread.Join();
}
This has the following advantages:
It smells like busy waiting, but it's not. $NUMBER_OF_SECONDS checks are done during the waiting phase, which is not comparable to the thousands of checks done in real busy waiting.
It's simple, which greatly reduces the risk of error in multi-threaded code. All your Stop method needs to do is to set m_shouldRun to false and (maybe) call Thread.Join (if it is necessary for the thread to finish before Stop is left). No synchronization primitives are needed (except for marking m_shouldRun as volatile).
I came up with separately scheduling the task:
using System;
using System.Threading;
namespace ProjectEuler
{
class Program
{
//const double cycleIntervalMilliseconds = 10 * 60 * 1000;
const double cycleIntervalMilliseconds = 5 * 1000;
static readonly System.Timers.Timer scanTimer =
new System.Timers.Timer(cycleIntervalMilliseconds);
static bool scanningEnabled = true;
static readonly ManualResetEvent scanFinished =
new ManualResetEvent(true);
static void Main(string[] args)
{
scanTimer.Elapsed +=
new System.Timers.ElapsedEventHandler(scanTimer_Elapsed);
scanTimer.Enabled = true;
Console.ReadLine();
scanningEnabled = false;
scanFinished.WaitOne();
}
static void scanTimer_Elapsed(object sender,
System.Timers.ElapsedEventArgs e)
{
scanFinished.Reset();
scanTimer.Enabled = false;
if (scanningEnabled)
{
try
{
Console.WriteLine("Processing");
Thread.Sleep(5000);
Console.WriteLine("Finished");
}
finally
{
scanTimer.Enabled = scanningEnabled;
scanFinished.Set();
}
}
}
}
}
In case of BackgroundWorker, a cancel can be reported by the e.Cancel - property of the DoWork - event handler.
How can I achieve the same thing with a Thread object?
Here is a full example of one way of doing it.
private static bool _runThread;
private static object _runThreadLock = new object();
private static void Main(string[] args)
{
_runThread = true;
Thread t = new Thread(() =>
{
Console.WriteLine("Starting thread...");
bool _localRunThread = true;
while (_localRunThread)
{
Console.WriteLine("Working...");
Thread.Sleep(1000);
lock (_runThreadLock)
{
_localRunThread = _runThread;
}
}
Console.WriteLine("Exiting thread...");
});
t.Start();
// wait for any key press, and then exit the app
Console.ReadKey();
// tell the thread to stop
lock (_runThreadLock)
{
_runThread = false;
}
// wait for the thread to finish
t.Join();
Console.WriteLine("All done.");
}
In short; the thread checks a bool flag, and keeps runing as long as the flag is true. I prefer this approach over calling Thread.Abort becuase it seems a bit nicer and cleaner.
Generally you do it by the thread's execute being a delegate to a method on an object, with that object exposing a Cancel property, and the long-running operation periodically chercking that property for tru to determine whether to exit.
for example
public class MyLongTunningTask
{
public MyLongRunninTask() {}
public volatile bool Cancel {get; set; }
public void ExecuteLongRunningTask()
{
while(!this.Cancel)
{
// Do something long running.
// you may still like to check Cancel periodically and exit gracefully if its true
}
}
}
Then elsewhere:
var longRunning = new MyLongTunningTask();
Thread myThread = new Thread(new ThreadStart(longRunning.ExecuteLongRunningTask));
myThread.Start();
// somewhere else
longRunning.Cancel = true;
A blocked thread can be stopped prematurely in one of two ways:
Thread.Interrupt
Thread.Abort
The main question is if the thread works on any ressources which need to be released correctly - in this case - you need to work with a property on the actual object which runs the thread.
There's Thread.Abort, which works by injecting a ThreadAbortException into the thread. It's a little risky because:
Your thread can get stuck if it's executing native code at the time
The code in the thread better be exception-safe, because this ThreadAbortException could happen on any line of code within it, even something innocent like i = i + 1
You're better off coding your own signalling mechanism between your GUI thread and the background thread. It's hard to recommend something without knowing what's going on inside that thread, but where I have a thread that works by waiting on some object in a loop, I use an AutoResetEvent and wait on that too.