If I do:
ConsoleApp1:
bool mutexCreated;
var mutex = new Mutex(true, "MemoryMappedFileMutex", out mutexCreated);
Console.Write("Run Console App2 then press enter");
Console.Read();
// do work
Thread.Sleep(5000);
mutex.ReleaseMutex(); // makes console app 2 to stop waiting
ConsoleApp2
var mutex = Mutex.OpenExisting("MemoryMappedFileMutex");
mutex.WaitOne();
// continue executing once console app 1 releases mutex
Everything works great. I have to start consoleApp1 first for this algorithm to work though.
Now my qestion is I will like consoleApp2 to act as the server. Therefore I will like to start that application first. The problem is that if I do:
bool mutexCreated;
var mutex = new Mutex(true, "MemoryMappedFileMutex", out mutexCreated);
mutex.WaitOne(); // <------ mutex will not wait why????
if I do mutex.WaitOne() that thread will not wait. In other words I want to start consoleApp2 first and have that application wait until I signal the mutex somehow on console application 1....
In your server app, try calling the constructor with false as the first parameter, so that the calling thread will not own the mutex initially.
Waiting on a Mutex from the owning thread does not block, and you specified true as the first Mutex constructor arg, which indicates it gets created already owned by the current thread.
Related
I have some problem with ThreadStart delegate. After I provide a function and start the thread nothing is actually happening. I need to add Console.Readline() to write messages to a file. Why it behaves like that?
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace ThreadStart
{
class Program
{
static void Main(string[] args)
{
Thread thread = new Thread(new System.Threading.ThreadStart(() =>
{
int messageSeq = 0;
while (messageSeq < 5)
{
File.AppendAllText(#"c:\Test\write.txt", DateTime.Now.ToString() + Environment.NewLine);
messageSeq++;
Thread.Sleep(TimeSpan.FromMinutes(1));
}
}));
thread.IsBackground = true;
thread.Start();
//Console.ReadLine();
}
}
}
I don't have experience in multi-threaded applications so i might be missing something simple
Thread.IsBackground Property
A thread is either a background thread or a foreground thread. Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating.
You're telling the thread not to force the application to stay running, and then you're letting the application close by returning from the Main method.
Console.ReadLine(); will stop the application returning from Main and will give the thread time to do it's work.
Thread.Start Method
Note that the call to Start does not block the calling thread.
The Start method of the Thread doesn't block the calling thread. That means it returns ~right away and the calling thread continues to execute.
Console.ReadLine Method
If the standard input device is the keyboard, the ReadLine method blocks until the user presses the Enter key.
Console.ReadLine() does block the calling thread until the user hits enter/return in the console (causing a new line).
In the past, I've created the main thread of a service using the Thread object. Now I'm attempting to update it to the TPL. Unfortunately, the service ends after one pass in my loop. What do I need to do to keep the Task alive?
protected override void OnStart(string[] args)
{
_workerThread = Task.Run(() =>
{
while (true)
{
Console.WriteLine("go");
Thread.Sleep(10000);
}
});
}
More info:
In order to debug the service, I've set a flag to start the service as a console app if Environment.UserInteractive is set to true. So I guess I need it to keep going in console mode as well as a service.
When you create a new Thread, it is a foreground thread by default (its IsBackground is set to false). What that means is that your console application won't end until the thread does, even if Main returns before that.
Tasks, on the other hand, run on the thread pool, which contains only background threads. This means that when your Main returns, the application will exit, even if there is some Task still running.
You can fix this by Waiting on the Task at the end of your Main.
I don't understand this behavior:
static Mutex Mut;
static void Main(string[] args)
{
try
{
Mut = System.Threading.Mutex.OpenExisting("testmut");
}
catch
{
Mut = new Mutex(true, "testmut");
}
Mut.WaitOne();
Thread.Sleep(4000);
Mut.ReleaseMutex();
}
Starting two instances of this application simultaneously will cause the second application to get an Abandoned Mutex Exception after the first process terminates. Why? I did explicitly release the mutex before terminating there in the first process.
Okay, the problem was simple. I actually gained Mutex ownership twice in the first process, first by calling Mut = new Mutex(true, "testmut"); (the true flag grants the caller ownership of the Mutex), and then doing a WaitOne(). Obviously, since I only freed it once in the end, I was getting an AM Exception.
I have a console application which will be initiated by different batch files set up windows task scheduler. I would like to queue these commands or have some sort of a lock mechanism in my application that would have all the commands waiting on a queue, so that only one command runs at a time. I was thinking about doing some sort of a file lock, but i cant get my head wrapped around to how would it work for queuing commands. I just need some sort of direction.
For inter-process synchronization, you may use a Mutex instance representing a named system mutex.
// Generate your own random GUID for the mutex name.
string mutexName = "afa7ab33-3817-48a4-aecb-005d9db945d4";
using (Mutex m = new Mutex(false, mutexName))
{
// Block until the mutex is acquired.
// Only a single thread/process may acquire the mutex at any time.
m.WaitOne();
try
{
// Perform processing here.
}
finally
{
// Release the mutex so that other threads/processes may proceed.
m.ReleaseMutex();
}
}
Look for Semaphore object.
_resultLock = new Semaphore(1, 1, "GlobalSemaphoreName");
if (!_resultLock.WaitOne(1000, false))
{
// timeout expired
}
else
{
// lock is acquired, you can do your stuff
}
You can always put your timeout to Infinite, but it is practical to get control over the program flow from time to time and be able to abort gracefully.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C#: Waiting for all threads to complete
I have a console app that spawns some threads and then exits. Each thread takes roughly ~20 seconds to complete. It appears as though the console app is spawning the threads and then exiting before the threads have a chance to complete.
How do I tell the console app not to exit until all threads it has spawned have completed?
You can to use a CountDownEvent.
using System;
using System.Collections.Generic;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static CountdownEvent countdown;
static void Main(string[] args)
{
countdown = new CountdownEvent(1);
for (int i = 1; i < 5; i++)
{
countdown.AddCount(); //add a count for each (BEFORE starting thread .. Thanks, Brian!)
//do stuff to start background thread
}
countdown.Signal(); //subtract your initial count
countdown.Wait(); //wait until countdown reaches zero
//done!
}
static void backgroundwork()
{
//work
countdown.Signal(); //signal this thread's completion (subtract one from count)
}
}
}
Are the threads spawned for a loop? If so a Parallel.ForEach would work:
ParallelOptions options = new ParallelOptions();
Parallel.ForEach(items, options, item=>
{
// Do Work here
});
As long as the Thread is not a background-thread (.IsBackground), the app should stay alive:
static void Main()
{
Thread thread = new Thread(MoreStuff);
thread.IsBackground = false;
thread.Start();
Console.WriteLine("Main thread exiting");
}
static void MoreStuff()
{
Console.WriteLine("Second thread starting");
Thread.Sleep(5000); // simulate work
Console.WriteLine("Second thread exiting");
}
Nothing else is needed. Note that the ThreadPool will use background threads; is the problem perhaps that you are using ThreadPool here?
Note: if the second thread hasn't actually started there might be a small race where it can exit prematurely; you might want to gate the threads starting.
You can use Thread.Join to wait for a thread to complete.
How are you launching the threads? It really depends, but if you are just using the Thread class, then call yourThread[i].Join() from the main thread to ensure that all threads complete.
Look into the Tasks and Task Factory to handle things a lot more cleanly than in years past.
Call Thread.Join() on all of the Threads that you start after they have started. This will block the current thread until the thread is complete.
You should probably use synchronization and wait for any spawned threads to complete their work, either by blocking the main thread with calls to Thread.Join or using signalling (e.g. using a Monitor or one of the other options for this).
Alternatively you can simply make the spawned threads run as foreground threads, by setting the IsForeground property (afaicr). This will keep the application alive until the threads have terminated, but you will still see the console window disappear as the main thread exits.