The question is that, what happens to a thread when the function has already been executed and the thread is started in that function. (please see an example below)
public int Intialise ()
{
int i = startServer();
Thread readall = new Thread(readAllMessage);
if (i == 1)
readall.Start();
else
MessageBox.Show("Connection Error");
return i;
}
I want 'readall' to continue (forever or till the application is closed) even if the function is executed. Is it possible? Because for me the thread stops immediately even when the true condition is met. Please shed some light.
OK, here is your code slightly modified to include the loop.
internal class Program
{
public static int Intialise()
{
int i = startServer();
Thread readall = new Thread(readAllMessage);
readall.IsBackground = true; // so that when the main thread finishes, the app closes
if (i == 1)
readall.Start();
else
Console.WriteLine("Error");
return i;
}
public static void readAllMessage()
{
while (true)
{
Console.WriteLine("reading...");
Thread.Sleep(500);
}
}
public static int startServer()
{
return 1;
}
private static void Main(string[] args)
{
var i = Intialise();
Console.WriteLine("Init finished, thread running");
Console.ReadLine();
}
}
when you run it, it will print:
Init finished, thread running
reading...
reading...
reading...
and when you press enter (see Console.ReadLine()) it will stop running.
If you change the IsBackground to TRUE it would not exit the process.
Here is an example of what you ask
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ForeverApp
{
class SomeObj
{
public void ExecuteForever()
{
while (true)
{
Thread.Sleep(1000);
Console.Write(".");
}
}
}
class Program
{
static void Main(string[] args)
{
SomeObj so = new SomeObj();
Thread thrd = new Thread(so.ExecuteForever);
thrd.Start();
Console.WriteLine("Exiting Main Function");
}
}
}
Related
This question already has answers here:
Wait for QueueUserWorkItem to Complete
(3 answers)
Closed 3 years ago.
I created very simple program and used Thread-pool for execute 3 task simultaneously. In this method 1 will print same message 9000 times (because using loop), method 2 and 3rd will print message 1 time. Now the problem is that, method 1 print message only few times and then program stop execution.
Some times not result display.
I know that if foreground thread will complete the task the all the background task will stop working. But how is it acceptable program stop working without completing task.
using System;
using System.Threading;
namespace ThreadingInCSharp
{
class Program
{
static void Main()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_1));
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_2));
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_3));
Thread.CurrentThread.IsBackground = false;
}
private static void Method_1(object obj)
{
for (int i = 0; i < 9000; i++)
{
Console.WriteLine("It's method 1");
}
}
private static void Method_2(object obj)
{
Console.WriteLine("It's method 2");
}
private static void Method_3(object obj)
{
Console.WriteLine("It's method 3");
}
}
}
Thread.CurrentThread.IsBackground = false;
That line will not do anything since there are no further instructions to wait for.
Simply add Console.ReadLine() and the end of Main.
static void Main()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_1));
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_2));
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_3));
Console.Write("Press ENTER to quit");
Console.ReadLine();
}
If you want to wait for all threads to complete, you can use thread synchronization objects like ManualResetEvent.
using System;
using System.Threading;
namespace ThreadingInCSharp
{
class Program
{
ManualResetEvent _method1Event = new ManualResetEvent(false);
ManualResetEvent _method2Event = new ManualResetEvent(false);
ManualResetEvent _method3Event = new ManualResetEvent(false);
static void Main()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_1));
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_2));
ThreadPool.QueueUserWorkItem(new WaitCallback(Method_3));
WaitHandle.WaitAll(new[]{_method1Event, _method2Event, _method3Event});
}
private static void Method_1(object obj)
{
for (int i = 0; i < 9000; i++)
{
Console.WriteLine("It's method 1");
}
_method1Event.Set();
}
private static void Method_2(object obj)
{
Console.WriteLine("It's method 2");
_method2Event.Set();
}
private static void Method_3(object obj)
{
Console.WriteLine("It's method 3");
_method3Event.Set();
}
}
}
WaitHandle.WaitAll will wait until all three events have been signaled (i.e. the methods have completed their work).
I create an example about thread,
I know that use lock could avoid thread suspending at critical section, but I have two questions.
1.Why my program get stuck if I use Thread.Sleep?
In this example, I add sleep to two thread.
Because I wish the console output more slowly, so I can easily see if there's anything wrong.
But if I use Thread.Sleep() then this program will get stuck!
2.What situation should I use Thread.Sleep?
Thanks for your kind response, have a nice day.
class MyThreadExample
{
private static int count1 = 0;
private static int count2 = 0;
Thread t1;
Thread t2;
public MyThreadExample() {
t1 = new Thread(new ThreadStart(increment));
t2 = new Thread(new ThreadStart(checkequal));
}
public static void Main() {
MyThreadExample mt = new MyThreadExample();
mt.t1.Start();
mt.t2.Start();
}
void increment()
{
lock (this)
{
while (true)
{
count1++; count2++;
//Thread.Sleep(0); stuck when use Sleep!
}
}
}
void checkequal()
{
lock (this)
{
while (true)
{
if (count1 == count2)
Console.WriteLine("Synchronize");
else
Console.WriteLine("unSynchronize");
// Thread.Sleep(0);
}
}
}
}
Please take a look at these following codes. Never use lock(this), instead use lock(syncObj) because you have better control over it. Lock only the critical section (ex.: only variable) and dont lock the whole while loop. In method Main, add something to wait at the end "Console.Read()", otherwise, your application is dead. This one works with or without Thread.Sleep. In your code above, your thread will enter "Increment" or "Checkequal" and the lock will never release. Thats why, it works only on Increment or Checkequal and never both.
internal class MyThreadExample
{
private static int m_Count1;
private static int m_Count2;
private readonly object m_SyncObj = new object();
private readonly Thread m_T1;
private readonly Thread m_T2;
public MyThreadExample()
{
m_T1 = new Thread(Increment) {IsBackground = true};
m_T2 = new Thread(Checkequal) {IsBackground = true};
}
public static void Main()
{
var mt = new MyThreadExample();
mt.m_T1.Start();
mt.m_T2.Start();
Console.Read();
}
private void Increment()
{
while (true)
{
lock (m_SyncObj)
{
m_Count1++;
m_Count2++;
}
Thread.Sleep(1000); //stuck when use Sleep!
}
}
private void Checkequal()
{
while (true)
{
lock (m_SyncObj)
{
Console.WriteLine(m_Count1 == m_Count2 ? "Synchronize" : "unSynchronize");
}
Thread.Sleep(1000);
}
}
}
Thread is a little bit old style. If you are a beginner of .NET and using .NET 4.5 or above, then use Task. Much better. All new multithreading in .NET are based on Task, like async await:
public static void Main()
{
var mt = new MyThreadExample();
Task.Run(() => { mt.Increment(); });
Task.Run(() => { mt.Checkequal(); });
Console.Read();
}
Is there anything except for Mutex to synchronise two processes in a fault-tolerant fashion? Please bear with me...
There is a process A, it's a bit flaky, it needs to start process B in the background and continue. If process A successfully does its thing, it needs to signal process B to dispose, and moves on (it doesn't terminate and thread is reused). If process A dies due to exception, termination, etc. process B needs to detect it quickly and dispose of itself on its own. Process A is not a "process" rather a library executed by various hosts hence process B can't just wait for process A's name to disappear.
Enter Mutex.
Here process A represented by a test fixture, if successful it'll call TestFixtureTearDown and move on, or test runner might be killed and TestFixtureTearDown is never executed. As with the actual process, TestFixtureTearDown might be called by a different thread to one that ran TestFixtureSetUp and created the mutex, hence ReleaseMutex sometimes throws ApplicationException : Object synchronization method was called from an unsynchronized block of code.
Can I force ReleaseMutex in TestFixtureTearDown if it's being executed by a different thread or abandon mutex some other way?
Is there an alternative to Mutex that I can use for such fault-tolerant "reverse" wait/monitor scenario? Preferably without implementing process A sending heartbeats to process B and process B tracking intervals and timing out? Mutex felt like such an elegant solution except for occasional ApplicationException on asyncs.
.
namespace ClassLibrary1
{
public class Class1
{
private Mutex _mutex;
private Process _process;
[TestFixtureSetUp]
public void TestFixtureSetUp()
{
_mutex = new Mutex(true, "foo");
_process = Process.Start("ConsoleApplication1.exe");
}
[Test]
public void Test1() { /* Do stuff */ }
[Test]
public void Test2() { /* Do async stuff */ }
[TestFixtureTearDown]
public void TestFixtureTearDown()
{
_mutex.ReleaseMutex();
_process.WaitForExit();
}
}
}
.
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var mutex = Mutex.OpenExisting("foo");
// Start doing stuff
try { mutex.WaitOne(); }
catch (AbandonedMutexException) { }
finally { mutex.ReleaseMutex(); }
// Finish doing stuff
}
}
}
Semaphores do not have thread affinity. You can release a semaphore on a different thread than it was acquired on. Use a semaphore with a count of 1.
I ended up using a mix of Mutex, Thread and ManualResetEvent. For the googling folk of the future here's a verbose test:
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using NUnit.Framework;
namespace MutexResetEvent.Tests
{
public class Class1
{
private Mutex _mutex;
private Thread _thread;
private Process _process;
private ManualResetEvent _event;
[SetUp]
public void SetUp()
{
Console.WriteLine("SetUp: #{0}", Thread.CurrentThread.ManagedThreadId);
_event = new ManualResetEvent(false);
_thread = new Thread(() =>
{
Console.WriteLine("Thread: #{0}", Thread.CurrentThread.ManagedThreadId);
_mutex = new Mutex(true, "MutexResetEvent");
_process = new Process
{
StartInfo =
{
FileName = "MutexResetEvent.Worker.exe",
//UseShellExecute = false,
//RedirectStandardOutput = true
}
};
//_process.OutputDataReceived += (o, a) => Console.WriteLine(a.Data);
_process.Start();
//_process.BeginOutputReadLine();
while (!_event.WaitOne(1000))
Console.WriteLine("Thread: ...");
Console.WriteLine("Thread: #{0}", Thread.CurrentThread.ManagedThreadId);
_mutex.ReleaseMutex();
_process.WaitForExit();
});
}
[Test]
public void Test()
{
Console.WriteLine("Test: #{0}", Thread.CurrentThread.ManagedThreadId);
_thread.Start();
for (var i = 0; i < 3; i++)
{
Console.WriteLine("Test: ...");
Thread.Sleep(1000);
}
/*
if (Guid.NewGuid().GetHashCode() % 3 == 0)
Environment.Exit(1);
//*/
}
[TearDown]
public void TearDown()
{
Console.WriteLine("TearDown: #{0}", Thread.CurrentThread.ManagedThreadId);
Task.Run(() =>
{
Console.WriteLine("Task: #{0}", Thread.CurrentThread.ManagedThreadId);
_event.Set();
//_thread.Join();
}).Wait();
for (var i = 0; i < 3; i++)
{
Console.WriteLine("TearDown: ...");
Thread.Sleep(1000);
}
}
}
}
.
using System;
using System.Threading;
namespace MutexResetEvent.Worker
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Worker: #{0}", Thread.CurrentThread.ManagedThreadId);
var mutex = Mutex.OpenExisting("MutexResetEvent");
try
{
while (!mutex.WaitOne(1000))
Console.WriteLine("Worker: ...");
}
catch (AbandonedMutexException)
{
Console.WriteLine("Worker: AbandonedMutexException");
}
Console.WriteLine("Worker: #{0}", Thread.CurrentThread.ManagedThreadId);
mutex.ReleaseMutex();
Console.WriteLine("Worker: WOO HOO");
Console.ReadLine();
}
}
}
Below code is not working usin Auto Reset event, what wrong i am doing ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Threaddd
{
class Program
{
static int num = 0;
static EventWaitHandle e = new AutoResetEvent(false);
static object o = new object();
static void Main(string[] args)
{
new Thread(Consumer).Start();
new Thread(Producer).Start();
}
static void Producer()
{
while (true)
{
if (num == 0)
{
num++;
Console.WriteLine("Produced " + num);
Thread.Sleep(1000);
e.Set();
e.WaitOne();
}
}
}
static void Consumer()
{
while (true)
{
if (num == 1)
{
Console.WriteLine("Consumed " + num);
Thread.Sleep(1000);
num--;
e.Set();
e.WaitOne();
}
else
{
e.WaitOne();
}
}
}
}
It looks like when the Producer thread calls e.Set(), it does not notify the Consumer thread immediately, so the Producer thread consumes the event when it calls e.WaitOne().
From http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
"There is no guarantee that every call to the Set method will release a thread. If two calls are too close together, so that the second call occurs before a thread has been released, only one thread is released. It is as if the second call did not happen. Also, if Set is called when there are no threads waiting and the AutoResetEvent is already signaled, the call has no effect."
One idea would be to use a separate event for each thread as the supplied link illustrates.
This is not a real consumer / producer pattern implementation.
e.Set() will release only ONE thread that is waiting using e.WaitOne()
So, when you write:
e.Set();
e.WaitOne();
On the producer thread, you are actually not enabling the consumer thread to get the signal
Try the following:
static void Producer()
{
while (true)
{
Thread.Sleep(1000);
Console.WriteLine("Produced " + num++);
e.Set();
}
}
static void Consumer()
{
while (true)
{
e.WaitOne();
Console.WriteLine("Consumed " + num);
}
}
If your okay with your consumer and producer thread running wild you can simplify your program by removing some of the sets and waitones:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Threaddd
{
internal class Program
{
private static int num = 0;
private static EventWaitHandle e = new AutoResetEvent(false);
private static object o = new object();
private static void Main(string[] args)
{
new Thread(Consumer).Start();
new Thread(Producer).Start();
}
private static void Producer()
{
while (true)
{
if (num == 0)
{
num++;
Console.WriteLine("Produced " + num);
Thread.Sleep(1000);
e.Set();
}
}
}
private static void Consumer()
{
while (true)
{
if (num == 1)
{
Console.WriteLine("Consumed " + num);
Thread.Sleep(1000);
num--;
e.WaitOne();
}
}
}
}
}
If that is not an option both your producer and consumer(s) must have their own events.
To keep num between 0 and 1 you can use the following pattern and lose the if statements:
class Program
{
static volatile int num = 0;
// Initialized set to ensure that the producer goes first.
static EventWaitHandle consumed = new AutoResetEvent(true);
// Initialized not set to ensure consumer waits until first producer run.
static EventWaitHandle produced = new AutoResetEvent(false);
static void Main(string[] args)
{
new Thread(Consumer).Start();
new Thread(Producer).Start();
}
static void Producer()
{
while (true)
{
consumed.WaitOne();
num++;
Console.WriteLine("Produced " + num);
Thread.Sleep(1000);
produced.Set();
}
}
static void Consumer()
{
while (true)
{
produced.WaitOne();
Console.WriteLine("Consumed " + num);
Thread.Sleep(1000);
num--;
consumed.Set();
}
}
}
It is worth pointing out that normally there is some kind of queue between the producer and the consumer so that the producer can create more than one item between each run of the consumer. The way I have written the above there is little point having the consumer and producer on separate threads as they will not be able to run at the same time.
I have a windows app and an an dll(windows form) that im trying to open (ActivationCheck), im trying to pause the current thread open a new thread (ActivationCheck) wait for that form event to return true then continue the main thread.
Could someone explain\show me what im doing wrong - thanks.
static class Program
{
private static SplashScreen splash;
private static bool quitApp;
private static bool activationFinished;
[STAThread]
static void Main()
{
Thread thread = new Thread(ActivationCheck);
thread.Start();
do
{
Thread.Sleep(1000);
} while (activationFinished);
if (!quitApp)
{
Thread.Sleep(0);
// WizardRun();
Application.Run(new Main(ref splash));
}
}
}
private static void ActivationCheck()
{
splash.SetStatus = "Checking License...";
Guid productId = new Guid(Properties.Settings.Default.ProductId);
Guid versionId = new Guid(Properties.Settings.Default.VersionId);
Client.UI.EntryPoint entryPoint = new EntryPoint();
activationFinished = false;
Client.BLL.ProductActivation.GenerateTrialLicense(productId1, versionId2, EditionId3);
entryPoint.IniatePlugin(productId, versionId);
entryPoint.PluginFinished += new EventHandlers.PluginFinishEventHandler(entryPoint_PluginFinished);
}
static void entryPoint_PluginFinished(bool forceQuit)
{
quitApp = forceQuit;
activationFinished = true;
}
You could just do thread.Join()? To be honest, though, I'm not quite sure what the point is of starting a second thread and pausing the first; just do the work on the original thread?
The problem with the code is possibly that activationFinished is being held in a register; try marking it as volatile, or alternatively use a lock at both places that access this variable. Even better would be to use a ManualResetEvent or similar, and open it from the activation code.
using System;
using System.Threading;
static class Program
{
static void Main()
{
new Thread(DoActivation).Start();
Console.WriteLine("Main: waiting for activation");
activation.WaitOne();
Console.WriteLine("Main: and off we go...");
}
static void DoActivation(object state)
{
Console.WriteLine("DoActivation: activating...");
Thread.Sleep(2000); // pretend this takes a while
Console.WriteLine("DoActivation: activated");
activation.Set();
// any other stuff on this thread...
}
static ManualResetEvent activation = new ManualResetEvent(false);
}