I am explaining my scenario, i have a function which print 1 to 10000 while printing i have to stop the process and let user know the current i value and if user presses enter it should continue again.
i am using
if ((Console.KeyAvailable) && (Console.ReadKey(true).Key == ConsoleKey.Escape))
but it doesn,t work, to complicate my task i am using threads, even if i manage to break this thread, child thread starts executing, i just want to stop the entire execution process for a moment and execute another function.
Check out the BackgroundWorker class, specifically, how to implement cancellation.
You'll basically need to check inside the loop if a cancellation is pending. If it is, then exit the loop.
If your using Threads. You can use this kind of code..
// Start
thread = new Thread(new ThreadStart(YourCommand));
thread.Start();
// Pause
if (thread != null)
{
thread.Suspend();
}
//Continue
if (thread != null)
{
thread.Resume();
}
//Alive
if (thread != null)
{
if (thread.IsAlive)
{
thread.Abort();
}
}
Or you can use timer....
Related
I have a looper thread that is running always and pull tasks from queue in order to execute them.
There is a main looper method
public void Start()
{
m_looperThread = new Thread(() =>
{
while (true)
{
//Dequeue use lock inside
TASK_TYPE task = m_taskList.GetAndRemoveFirst();
if (task == null || !m_isThreadRunning)
{
break;
}
task.Execute();
FinishedTask(task);
}
}
)
{
IsBackground = true
};
m_looperThread.Start();
}
Now if I need to close an application, user need to click red cross and before closing I need to abort all looper tasks.
How I do it
public void Abort()
{
Put(default(TASK_TYPE));
m_isThreadRunning = false;
if (m_looperThread != null)
{
m_looperThread.Join();
}
m_taskList.Clear();
}
So, first of all I put a null item and additional I set m_isThreadRunning value to false because in looper method I am checking this values in order to stop it. Then I call .Join() to make sure that I finished this thread and clear task list. Now I know exactly that all tasks were aborted, threads were joined and all is fine.
But issue here in this line
task.Execute();
What is the issue - when task run and user need to close the application I can't .Join the looper thread before task finish the job (it could be 1 minute). And finally it is looks like application in stuck.
So, question is - how correctly .join the thread and give to user opportunity to close the application?
I have a WPF application in which i have this class :
public partial class Global : UserControl
{
public static List<Thread> listofthreads = new List<Thread>();
public Global()
{
InitializeComponent();
Thread windowThread = new Thread(delegate() { verifing(); });
listofthreads.Add(windowThread);
windowThread.Start();
}
public void verifing()
{
if (Global2.Pat_pathregfile.Length > 5 && Global2.Pat_pathcalibfile.Length > 5) {
if (utilisation.Dispatcher.CheckAccess())
{
utilisation.Visibility = Visibility.Visible;
}
else
{
utilisation.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
utilisation.Visibility = Visibility.Visible;
}));
}
foreach (Thread t in listofthreads) {
try
{
t.Suspend();
}
catch { }
}
}
else {
if (utilisation.Dispatcher.CheckAccess())
{
utilisation.Visibility = Visibility.Hidden;
}
else
{
utilisation.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
{
utilisation.Visibility = Visibility.Hidden;
}));
}
Thread windowThread = new Thread(delegate() { verifing(); });
windowThread.Start();
listofthreads.Add(windowThread);
}
}
}
i need to kill properly all of the threads that i have used
foreach (Thread t in listofthreads) {
try
{
t.Suspend();
}
catch { }
}
But the program indicates that the use of the method suspend isn't recommended .
Why?
It seems that some threads is still working even after the close of the windows, Why this happens? How can i fix it?
Is another method of killing a thread exist in wpf?
1) Why?
Suspend method has been marked as Obsolete by Microsoft. Error states itself:
Thread.Suspend has been deprecated. Please use other classes in
System.Threading, such as Monitor, Mutex, Event, and Semaphore, to
synchronize Threads or protect resources.
2) It seems that some threads is still working even after the close of
the windows, Why this happens? How can i fix it?
You have started all threads as foreground thread which won't stop automatically when main thread finishes its execution. In case you want to stop all threads once all foreground threads stops, you should mark thread as background thread.
windowThread.IsBackground = true;
3) Is another method of killing a thread exist in wpf?
Use Thread.Abort(). However, closing your main thread will automatically stop all background threads (IsBackground set to true on thread), you should not worry about killing them.
What are you trying to do? You are creating threads just for the purpose of checking some condition? And when the condition is true, you change the visibility and block all threads(!) from further execution. And when the condition is not true, you create another thread that does the same. Why are you suspending all threads (including the active one) instead of just letting it terminate? And if you want to periodically check for a condition, use a timer or a wait event instead.
Just as a side note: Your foreach-loops will eventually throw InvalidOperationException, because you're changing the collection without a lock.
And then, don't try to kill threads. Use flags or signals instead. Any attempt to kill threads is a) bad design and b) prone to errors and unexpected behavior.
I have a kept a polling timer to check if a process is running or not. I have the following simple code for this:
bool alreadyChecked = false; //check if the wait to check the second time is already over
**Timer_elapsed event**
Process sampleProcess[] = Process.GetProcessesByName("notepad");
if(sampleProcess.length > 0)
{
//Process is running
return;
}
else
{
//Process is not running, so do the following
//Wait for some time and check again (set alreadyChecked = true when the wait is over)
if (alreadyChecked){
//Run the process}
else{
//The process has started running while we were waiting
return;}
}
I am not able to implement the waiting code inside the event, so that it can wait and then fire the event again. (Even if we implement the wait time, the Timer_elapsed event will be fired by timer again while we were waiting.)
Any suggestions?
You should create a separate thread and use the sleep method, using a BackgroundWorker is the best option. You can also use a timer thread.
**BackgroundWorker_DoWork event**
int nTrials = 0; // this method will help you pick any number of trials before launching the applicaion
bool isRunning = false;
while((isRunning = Process.GetProcessesByName("notepad") == 0) || nTrials < 2)
{
Thread.Sleep(1000); // w8 1 second before queriying the process name
nTrials++;
}
if ( isRunning ) RunProcess();
Don't use the sleep method on your main thread or your application will stop handling messages for the sleep time.
I am looking for a simple way to put a thread to sleep and to wake it. The thread runs in background in an infinite loop and sometimes does some work, sometimes just runs through. I have found out that there is no corresponding Wait() to the Sleep() and waking a thread with Interrupt() causes an exception. Apparently a sleeping thread is not meant to be disturbed.
Since I know when the work appears it seems a good idea to tell the thread, instead of having it check over and over again.
How can a thread be put to a 'lighter sleep' to be able to wake up alone each second or at a command from other thread?
//Thread to put to sleep and wake (thread1)
while (true)
{
if (thereIsWork)
{ DoWork(); }
//put thread to sleep in a way that other threads can wake it, and it wakes alone after some time (eg. 1000 ms)
// Thread.Sleep(1000); //nice, but not working as desired
}
-
//Other thread:
thereIsWork = true;
//thread1.Wake(); //Not existing
You can use an AutoResetEvent for this - just call Set() to signal work needs to be done and have your thread wait for it to be called using WaitOne().
This means the threads that are communicating this way share the same AutoResetEvent instance - you can pass it in as a dependency for the thread that does the actual work.
The thread shouldn't Sleep(), it should call WaitOne() on an AutoResetEvent or ManualResetEvent until some other thread calls Set() on that same resetevent object.
How about using a blocking queue, with Monitor Pulse and Wait:
class BlockingQueue<T>
{
private Queue<T> _queue = new Queue<T>();
public void Enqueue(T data)
{
if (data == null) throw new ArgumentNullException("data");
lock (_queue)
{
_queue.Enqueue(data);
Monitor.Pulse(_queue);
}
}
public T Dequeue()
{
lock (_queue)
{
while (_queue.Count == 0) Monitor.Wait(_queue);
return _queue.Dequeue();
}
}
}
Then thread 1 becomes
BlockingQueue<Action> _workQueue = new BlockingQueue<Action>();
while (true)
{
var workItem = _workQueue.Dequeue();
workItem();
}
And the other thread:
_workQueue.Enqueue(DoWork);
NB: you should probably use the built in type if you're using .Net 4 BlockingCollection using Add and Take instead of Enqueue and Dequeue.
Edit:
Ok. If you want it really simple...
//Thread to put to sleep and wake (thread1)
while (true)
{
lock(_lock)
{
while (!thereIsWork) Monitor.Wait(_lock);
DoWork();
}
//put thread to sleep in a way that other threads can wake it, and it wakes alone after some time (eg. 1000 ms)
// Thread.Sleep(1000); //nice, but not working as desired
}
and
//Other thread:
lock(_lock)
{
thereIsWork = true;
//thread1.Wake(); //Not existing
Monitor.Pulse(_lock);
}
I'n not an expert with threads, but maybe EventWaitHandle is what you're looking for. Check this link
when parent thread sleep does sub threads also sleep ?
Now main thread is UI
I create 20 sub threads inside main thread with task factory (lets call threads 2)
Inside of this 20 sub threads i create another 10 sub threads again with sub factory (lets call threads 3)
Now inside of this threads 2 i have infinite loop. Inside of infinite loop checking whether threads 3 completed or not. If completed dispose completed thread and start another thread. I am using 250 ms sleep for each checking inside infinite while loop. So when threads 2 in sleep does also threads 3 sleep or they are independent. Here the code you can see.
while (true)
{
int irActiveThreadCount = 0;
int irFinishedLast = -1;
for (int i = 0; i < irPerMainSiteThreadCount; i++)
{
if (MainSitesTaskList[irWhichMainTask, i] == null)
{
irFinishedLast = i;
break;
}
if (MainSitesTaskList[irWhichMainTask, i].IsCompleted == true)
{
irFinishedLast = i;
break;
}
}
for (int i = 0; i < irPerMainSiteThreadCount; i++)
{
if (MainSitesTaskList[irWhichMainTask, i] != null)
if (MainSitesTaskList[irWhichMainTask, i].IsCompleted == false)
{
irActiveThreadCount++;
}
}
if (irFinishedLast > -1)
{
var newTask = Task.Factory.StartNew(() =>
{
fcStartSubPageCrawl(srMainSiteURL, srMainSiteId, irWhichMainTask);
});
lock (lockerMainSitesArray)
{
if (MainSitesTaskList[irWhichMainTask, irFinishedLast] != null)
MainSitesTaskList[irWhichMainTask, irFinishedLast].Dispose();
MainSitesTaskList[irWhichMainTask, irFinishedLast] = newTask;
}
}
Thread.Sleep(250);
srQuery = "myquery";
using (DataSet dsTemp = DbConnection.db_Select_Query(srQuery))
{
if (dsTemp != null)
if (dsTemp.Tables.Count > 0)
if (dsTemp.Tables[0].Rows.Count == 0)
{
break;
}
}
}
There's no such thing as a "parent" thread really. One thread starts another, but then there's no particular relationship between them. For example, the starting thread can terminate without any of the new threads dying.
The starting thread sleeping definitely doesn't affect any other thread.
There is no concept of parent and child threads. One implication of this is that the child threads don't sleep when the parent thread sleeps.
Thread.Sleep(...)
only suspends the current Thread.
check here: Thread.Sleep Method
so all other threads will keep working.
Each thread is always totally independant. The only possible connection between threads is that when all the non-background thread finish, the program ends, so the background threads die. If a thread sleeps, the other threads continue working (and probably go faster, because there is one less thread working). If you need to sync threads, there are various classes to do it (in general locks (not a class), mutexes, semaphores...)
The others are right, there is no concept of “parent threads” in .Net. And waiting on one thread doesn't cause other threads to wait (unless there is some synchronization involved, like using locks).
But there's another point: your code doesn't create new threads, at least not necessarily. When you call Task.Factory.StartNew(), the task is usually scheduled on a thread pool thread. If there isn't any thread available and the number of threads didn't reach the maximum allowed number yet, new thread is created. But in other cases, it isn't. The task is either going to reuse existing idle thread, or it's going to wait, until one becomes available.