How to check if a thread is running in C #? - c#

I created a thread in C # 4.0 and would like to know how do I check if it is running?

You can use Thread.IsAlive to check to see if a Thread is running.
That being said, if you're using C# 4, it's rarely a good idea to make "threads" manually. You should consider using the TPL and the Task/Task<T> class, as this provides a much cleaner model to attach work to run after the task completes, pull data out of the operation, etc.

I use Mutex to verify this. Sometimes just verify is Thread is alive with Thread.IsAlive is not safe if you are running on Background.
Try this:
private void btnDoSomething()
{
try
{
string nameThread = "testThreadDoSomething";
var newThread = new Thread(delegate() { this.DoSomething(nameThread); });
newThread.IsBackground = true;
newThread.Name = nameThread;
newThread.Start();
//Prevent optimization from setting the field before calling Start
Thread.MemoryBarrier();
}
catch (Exception ex)
{
}
}
public void DoSomething(string threadName)
{
bool ownsMutex;
using (Mutex mutex = new Mutex(true, threadName, out ownsMutex))
{
if (ownsMutex)
{
Thread.Sleep(300000); // 300 seconds
if (Monitor.TryEnter(this, 300))
{
try
{
// Your Source
}
catch (Exception e)
{
string mensagem = "Error : " + e.ToString();
}
finally
{
Monitor.Exit(this);
}
}
//mutex.ReleaseMutex();
}
}
}

Related

Prevent running multiple instances of a mono app

I know how to prevent running multiple instances of a given app on Windows:
Prevent multiple instances of a given app in .NET?
This code does not work under Linux using mono-develop though. It compiles and runs but it does not work. How can I prevent it under Linux using mono?
This is what I have tried but the code deos not work under linux only on windows.
static void Main()
{
Task.Factory.StartNew(() =>
{
try
{
var p = new NamedPipeServerStream("SomeGuid", PipeDirection.In, 1);
Console.WriteLine("Waiting for connection");
p.WaitForConnection();
}
catch
{
Console.WriteLine("Error another insance already running");
Environment.Exit(1); // terminate application
}
});
Thread.Sleep(1000);
Console.WriteLine("Doing work");
// Do work....
Thread.Sleep(10000);
}
I came up with this answer. Call this method passing it a unique ID
public static void PreventMultipleInstance(string applicationId)
{
// Under Windows this is:
// C:\Users\SomeUser\AppData\Local\Temp\
// Linux this is:
// /tmp/
var temporaryDirectory = Path.GetTempPath();
// Application ID (Make sure this guid is different accross your different applications!
var applicationGuid = applicationId + ".process-lock";
// file that will serve as our lock
var fileFulePath = Path.Combine(temporaryDirectory, applicationGuid);
try
{
// Prevents other processes from reading from or writing to this file
var _InstanceLock = new FileStream(fileFulePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
_InstanceLock.Lock(0, 0);
MonoApp.Logger.LogToDisk(LogType.Notification, "04ZH-EQP0", "Aquired Lock", fileFulePath);
// todo investigate why we need a reference to file stream. Without this GC releases the lock!
System.Timers.Timer t = new System.Timers.Timer()
{
Interval = 500000,
Enabled = true,
};
t.Elapsed += (a, b) =>
{
try
{
_InstanceLock.Lock(0, 0);
}
catch
{
MonoApp.Logger.Log(LogType.Error, "AOI7-QMCT", "Unable to lock file");
}
};
t.Start();
}
catch
{
// Terminate application because another instance with this ID is running
Environment.Exit(102534);
}
}

Queue problems across multiple threads

There are many questions and articles on the subject of using a .NET Queue properly within a multi threaded application, however I can't find subject on our specific problem.
We have a Windows Service that receives messages onto a queue via one thread and is then dequeued and processed within another.
We're using lock when queuing and dequeuing, and the service had run fine for around 2 years without any problems. One day we noticed that thousands of messages had been logged (and so had been queued) but were never dequeued/processed, they seem to have been skipped somehow, which shouldn't be possible for a queue.
We can't replicate the circumstances that caused it as we have no real idea what caused it considering that day was no different from any of the others as far as we're aware.
The only idea we have is to do with the concurrency of the queue. We're not using the ConcurrentQueue data-type, which we plan on using in the hope it is a remedy.
One idea, looking at the source of the Queue type, is that it uses arrays internally, which have to be resized once these buffers have reached a certain length. We hypothesised that when this is being done some of the messages were lost.
Another idea from our development manager is that using multiple threads on a multicore processor setup means that even though locks are used, the individual cores are working on the data in their local registers, which can cause them to be working on different data. He said they don't work on the same memory and seems to think lock only works as expected one a single core processor using multiple threads.
Reading more about ConcurrentQueue's use of volatile I'm not sure that this would help, as I've read that using lock provides a stronger guarantee of threads using the most up-to-date state of memory.
I don't have much knowledge on this specific subject, so my question is whether the manager's idea sounds plausible, and whether we might have missed something that's required for the queue to be used properly.
Code snippet for reference (forgive the messy code, it does need refactoring):
public sealed class Message
{
public void QueueMessage(long messageId, Message msg)
{
lock (_queueLock)
{
_queue.Enqueue(new QueuedMessage() { Id = messageId, Message = msg });
}
}
public static void QueueMessage(string queueProcessorName, long messageId, Message msg)
{
lock (_messageProcessors[queueProcessorName]._queueLock)
{
_messageProcessors[queueProcessorName].QueueMessage(messageId, msg);
_messageProcessors[queueProcessorName].WakeUp(); // Ensure the thread is awake
}
}
public void WakeUp()
{
lock(_monitor)
{
Monitor.Pulse(_monitor);
}
}
public void Process()
{
while (!_stop)
{
QueuedMessage currentMessage = null;
try
{
lock (_queueLock)
{
currentMessage = _queue.Dequeue();
}
}
catch(InvalidOperationException i)
{
// Nothing in the queue
}
while(currentMessage != null)
{
IContext context = new Context();
DAL.Message msg = null;
try
{
msg = context.Messages.SingleOrDefault(x => x.Id == currentMessage.Id);
}
catch (Exception e)
{
// TODO: Handle these exceptions better. Possible infinite loop.
continue; // Keep retrying until it works
}
if (msg == null) {
// TODO: Log missing message
continue;
}
try
{
msg.Status = DAL.Message.ProcessingState.Processing;
context.Commit();
}
catch (Exception e)
{
// TODO: Handle these exceptions better. Possible infinite loop.
continue; // Keep retrying until it works
}
bool result = false;
try {
Transformation.TransformManager mgr = Transformation.TransformManager.Instance();
Transformation.ITransform transform = mgr.GetTransform(currentMessage.Message.Type.Name, currentMessage.Message.Get("EVN:EventReasonCode"));
if (transform != null){
msg.BeginProcessing = DateTime.Now;
result = transform.Transform(currentMessage.Message);
msg.EndProcessing = DateTime.Now;
msg.Status = DAL.Message.ProcessingState.Complete;
}
else {
msg.Status = DAL.Message.ProcessingState.Failed;
}
context.Commit();
}
catch (Exception e)
{
try
{
context = new Context();
// TODO: Handle these exceptions better
Error err = context.Errors.Add(context.Errors.Create());
err.MessageId = currentMessage.Id;
if (currentMessage.Message != null)
{
err.EventReasonCode = currentMessage.Message.Get("EVN:EventReasonCode");
err.MessageType = currentMessage.Message.Type.Name;
}
else {
err.EventReasonCode = "Unknown";
err.MessageType = "Unknown";
}
StringBuilder sb = new StringBuilder("Exception occured\n");
int level = 0;
while (e != null && level < 10)
{
sb.Append("Message: ");
sb.Append(e.Message);
sb.Append("\nStack Trace: ");
sb.Append(e.StackTrace);
sb.Append("\n");
e = e.InnerException;
level++;
}
err.Text = sb.ToString();
}
catch (Exception ne) {
StringBuilder sb = new StringBuilder("Exception occured\n");
int level = 0;
while (ne != null && level < 10)
{
sb.Append("Message: ");
sb.Append(ne.Message);
sb.Append("\nStack Trace: ");
sb.Append(ne.StackTrace);
sb.Append("\n");
ne = ne.InnerException;
level++;
}
EventLog.WriteEntry("Service", sb.ToString(), EventLogEntryType.Error);
}
}
try
{
context.Commit();
lock (_queueLock)
{
currentMessage = _queue.Dequeue();
}
}
catch (InvalidOperationException e)
{
currentMessage = null; // No more messages in the queue
}
catch (Exception ne)
{
StringBuilder sb = new StringBuilder("Exception occured\n");
int level = 0;
while (ne != null && level < 10)
{
sb.Append("Message: ");
sb.Append(ne.Message);
sb.Append("\nStack Trace: ");
sb.Append(ne.StackTrace);
sb.Append("\n");
ne = ne.InnerException;
level++;
}
EventLog.WriteEntry("Service", sb.ToString(), EventLogEntryType.Error);
}
}
lock (_monitor)
{
if (_stop) break;
Monitor.Wait(_monitor, TimeSpan.FromMinutes(_pollingInterval));
if (_stop) break;
}
}
}
private object _monitor = new object();
private int _pollingInterval = 10;
private volatile bool _stop = false;
private object _queueLock = new object();
private Queue<QueuedMessage> _queue = new Queue<QueuedMessage>();
private static IDictionary<string, Message> _messageProcessors = new Dictionary<string, Message>();
}
so my question is whether the manager's idea sounds plausible
Uhm. No. If all those synchronization measures would only work on single core machines, the world would have ended in complete Chaos decades ago.
and whether we might have missed something that's required for the queue to be used properly.
As far as your description goes, you should be fine. I would look at how you found out that you have that problem. logs coming in but then vanishing without being properly dequeued, wouldn't that be the default case if I simply turned off the service or rebooted the machine? Are you sure you lost them while your application was actually running?
You declare the object to be used for the lock as private object.
If you try this:
class Program
{
static void Main(string[] args)
{
Test test1 = new Test();
Task Scan1 = Task.Run(() => test1.Run("1"));
Test test2 = new Test();
Task Scan2 = Task.Run(() => test2.Run("2"));
while(!Scan1.IsCompleted || !Scan2.IsCompleted)
{
Thread.Sleep(1000);
}
}
}
public class Test
{
private object _queueLock = new object();
public async Task Run(string val)
{
lock (_queueLock)
{
Console.WriteLine($"{val} locked");
Thread.Sleep(10000);
Console.WriteLine($"{val} unlocked");
}
}
}
You will notice that the code that lies under the lock is executed even if another thread is running inside.
But if you change
private object _queueLock = new object();
To
private static object _queueLock = new object();
It changes how your lock works.
Now, this being your issue depends on if you have multiple instances that class or everything is running withing that same class.

Threads in c# to be executed at 1 minute intervals of server time

I have created a thread in my c# application. its code is given below.
[WebMethod]
public void start()
{
Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
thread.Start();
}
[WebMethod]
public void stop()
{
Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
thread.Abort();
}
public void WorkThreadFunction()
{
try
{
TimeZone zone = TimeZone.CurrentTimeZone;
DateTime dt = DateTime.Now.AddHours(12);
dt = dt.AddMinutes(30);
TimeSpan offset = zone.GetUtcOffset(DateTime.Now);
String s = "insert into tb_log(timestamp) values('" + dt + "')";
Class1 obj = new Class1();
string res = obj.executequery(s);
}
catch
{
}
}
When I run this code the value enters only at one time into the table. I need to execute this thread at 1 min intervals throughout the day, week and year. How to make this possible? Also correct me if the code which I had written is correct or not. I'm new to threads in c#. So someone please help me out. Thanks and Regards..
public WebServiceClass : WebService
{
private boolean terminated = false;
private boolean running = false;
[WebMethod]
public void start()
{
if (running)
{
//Already Running!
}
else
{
running = true;
terminated = false;
//Start a new thread to run at the requested interval
Thread thread = new Thread(new ThreadStart(WorkThreadFunction));
thread.Start();
}
}
[WebMethod]
public void stop()
{
//tell the thread to stop running after it has completed it's current loop
terminated = true;
}
public void WorkThreadFunction()
{
try
{
DateTime nextLoopStart = DateTime.Now;
while (!terminated)
{
TimeZone zone = TimeZone.CurrentTimeZone;
DateTime dt = DateTime.Now.AddHours(12);
dt = dt.AddMinutes(30);
TimeSpan offset = zone.GetUtcOffset(DateTime.Now);
String s = "insert into tb_log(timestamp) values('" + dt + "')";
Class1 obj = new Class1();
string res = obj.executequery(s);
while (DateTime.Now < nextLoopStart)
{
System.Threading.Thread.Sleep(100);
}
nextLoopStart += new TimeSpan(0,1,0);
}
//Reset terminated so that the host class knows the thread is no longer running
}
catch (ThreadAbortException)
{
//LogWarning("INFO: Thread aborted");
}
catch (Exception e)
{
//LogError("Error in Execute: " + e.Message);
}
finally
{
running = false;
}
}
}
I would use the Timer class in C#. I am not familiar with ASP.NET but I presume the following link would help. http://msdn.microsoft.com/en-us/library/system.web.ui.timer(v=vs.110).aspx
Create an instance of the timer, set the elapsed time in milliseconds and attach your method to the timer's tick event. This method would then be invoked after every x milliseconds.
EDIT: To run the task on a different thread, run it as a task(.NET 4.0 or upwards)
timer.tick += (s,e)=>{
TaskFactory.StartNew(()=> WorkThreadFunction());
};
Please note, exception handling has been ignored for simplicity.
For a simple solution I would use Timer class.
Actually there are 3 Timer classes in .NET, so it depends on your use. The most general is - System.Threading.Timer
For more robust and full solution I would use a timing framework, for example Quartz.NET
http://www.quartz-scheduler.net/
It all depends on your specific needs.
Try the following UPDATED
public class myApp
{
public System.Diagnostics.EventLog myEventLog { get; set; }
private Thread appThread;
public int TimerIntervalSeconds {get; set;}
public void Start()
{
appThread = new Thread(new ThreadStart(WorkThreadFunction));
appThread.Start();
}
public void Stop()
{
if (appThread != null)
{
appThread.Abort();
appThread.Join();
}
}
private void WorkThreadFunction()
{
// Loop until the thread gets aborted
try
{
while (true)
{
WriteToDatabase();
// Sleep for TimerIntervalSeconds
Thread.Sleep(TimerIntervalSeconds * 1000);
}
}
catch (ThreadAbortException)
{
myEventLog.WriteEntry("INFO: Thread aborted", System.Diagnostics.EventLogEntryType.Warning);
}
catch (Exception e)
{
myEventLog.WriteEntry("Error in Execute: " + e.Message, System.Diagnostics.EventLogEntryType.Error);
}
}
}
This is the 'complete' class. Call Start to set it off and Stop to end it. Set TimerIntervalSeconds for the frequency you want the event to happen.
I didn't have time initially to give the whole solution.

Continue the application even if a thirdparty application fails

I have a thirdparty exe file name Projtest.exe and using a c# console application written by myself for running the Projtest.exe through commandline.
i was able to succeed in writing the application,but my issue is that due to some unknown reasons Projtest.exe stops working and throws an error window.My application is stucking at this point.What i want is to continue my application if Projtest.exe throws an error window.How can i do that.Part of my code is given below.
try
{
var pro = new Process
{
StartInfo = {
Arguments = string.Format("Projtest.exe {0} {1} ", arg1, arg2)
}
};
pro.Start();
pro.WaitForExit();
var exit = pro.ExitCode;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
What you can to do is regularly check if 'pro' is responding say every 10 seconds.
You can do this simply with a timer or you could create a thread to do it.
Also it is worth checking for exit here as well so you don't block your application.
Here is an example with a timer.
static Timer appCheck = new Timer();
static Process pro;
static void Main(string[] args)
{
appCheck.Interval = (10000); // set timer interval in ms
appCheck.AutoReset = true;
appCheck.Elapsed += new ElapsedEventHandler(appCheck_Tick);
try
{
pro = new Process
{
StartInfo =
{
Arguments = string.Format(#"Projtest.exe"),
FileName = string.Format(#"Projtest.exe")
}
};
pro.Start(); // starts your program
appCheck.Start(); // starts the timer to keep a watch on your program
while (true) // this just keeps your console window open. if you use waitForExit your application will be blocked and the timer won't fire.
{
}
//pro.WaitForExit();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
static void appCheck_Tick(object sender, EventArgs e)
{
if (!pro.HasExited)
{
if (pro.Responding == false)
{
appCheck.Stop(); // stop the timer so you don't keep getting messages
Console.WriteLine("Not responding");
}
}
else
{
appCheck.Stop(); // stop the timer so you don't keep getting messages
Console.WriteLine("exited");
}
}

Delete file using C# Thread

I was reading this article (Can't delete a file using threads) about my problem but things are getting difficult to me.
My problem is really simple, I just want to delete this old file, if I start the method "dlMoveNovaVersao" normally the file is deleted but if I put this on a thread (like bellow) I got "You are not allow". Someone knows what's the problem? (I wanna use thread).
private void verificaVersaoSupervisor_Tick(object sender, EventArgs e)
{
Thread threadConexao = new Thread(threadVerificaConexao);
threadConexao.Start();
}
public void threadVerificaConexao()
{
try
{
Dns.GetHostEntry("www.google.com.br");
if (verificaVersao())
{
try
{
verificaKillSupervisor();
dlMoveNovaVersao();
Application.Exit();
}
catch (Exception)
{ }
}
else
{
Application.Exit();
}
}
catch (Exception)
{ }
}
public void dlMoveNovaVersao()
{
WebClient webClient = new WebClient();
webClient.DownloadFile("Anywebsite", #"c:\temp\supervisor.exe);
try
{
File.Delete(#"c:\Test\supervisor.exe); //This file is always there!
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
Just discribe the purpose, My program (Supervisor Starter) check on website if I have an old version of "Supervisor" running (using XML), If it's true my "Supervisor Starter" verify if there is a process called "Supervisor" running and kill it after that "Supervisor Starter" download the new version and run it. (The program is small and the update don't take more then 4 seconds).
The problem start when my "Supervisor Starter" try delete the old version of my program. If I use thread I receive "I haven't permission to access the file", if I use the same method on Form class the file is deleted.
I suspect that you're running the thread while the file is in use. When the thread runs, it runs in parallel with the current thread. Have you ensured that that file is closed?.
Otherwise I think that the thread maybe being created with a credentials that are not yours. But I'm pretty sure this is not the case.
See if this is different for each case
catch (Exception err)
{
MessageBox.Show("User {0}. Message {1}",
System.Security.Principal.WindowsIdentity.GetCurrent().Name,
err.Message);
}
This is my functions for deleting files in threads if the files are in used
private static void Delete(System.IO.FileInfo file)
{
if (file.Exists)
{
int Attempt = 0;
bool ShouldStop = false;
while (!ShouldStop)
{
if (CanDelete(file))
{
file.Delete();
ShouldStop = true;
}
else if (Attempt >= 3)
{
ShouldStop = true;
}
else
{
// wait one sec
System.Threading.Thread.Sleep(1000);
}
Attempt++;
}
}
}
private static bool CanDelete(System.IO.FileInfo file)
{
try
{
//Just opening the file as open/create
using (FileStream fs = new FileStream(file.FullName, FileMode.OpenOrCreate))
{
//If required we can check for read/write by using fs.CanRead or fs.CanWrite
}
return false;
}
catch (IOException ex)
{
//check if message is for a File IO
string __message = ex.Message.ToString();
if (__message.Contains("The process cannot access the file"))
return true;
else
throw;
}
}

Categories