thread start stop c# WinForm - c#

Background:
In C# WinForm, I use several Threads like this
private Thread Thread1;
Thread1 = new Thread(new ThreadStart(DoSomething));
Thread1.Start();
And I want to set a timer to Stop/Kill the Thread1 every hour, and restart a new Thread1 like this:
Abort/Kill Thread1;
Thread1 = new Thread(new ThreadStart(DoSomething));
Thread1.Start();
So How to kill the thread1 and restart a new one without Restart my Winform?
Thank you kindly for your reply. I much appreciated it

You can do so by having a while loop in DoSomething that continues based on a volatile bool. Please see Groo's answer here:
Restarting a thread in .NET (using C#)

Here is a sample.
private void button1_Click(object sender, EventArgs e) {
var i = 0;
Action DoSomething = () => {
while (true) {
(++i).ToString();
Thread.Sleep(100);
}
};
Thread Thread1;
Thread1 = new Thread(new ThreadStart(DoSomething));
Thread1.Start();
Thread.Sleep(1000);
Text = i.ToString();
Thread1.Abort();
Thread1 = new Thread(new ThreadStart(DoSomething));
Thread1.Start();
}
I don't recommend Thread.Abort method.
When possible, design the thread what can stop safety. And use Join method.
private void button2_Click(object sender, EventArgs e) {
// the flag, to stop the thread outside.
var needStop = false;
var i = 0;
Action DoSomething = () => {
while (!needStop) {
(++i).ToString();
Thread.Sleep(100);
}
};
Thread Thread1;
Thread1 = new Thread(new ThreadStart(DoSomething));
Thread1.Start();
Thread.Sleep(1000);
Text = i.ToString();
// change flag to stop.
needStop = true;
// wait until thread stop.
Thread1.Join();
// start new thread.
Thread1 = new Thread(new ThreadStart(DoSomething));
Thread1.Start();
// needStop = true;
// Thread1.Join();
}

Related

Call a Method from thread1 to thread2?

First: What I want to do?
I want to run multiple jobs on one thread, for example, I want to make a thread for calculations and always run methods inside of that.
Get a pointer like SynchronizationContext.Current or Thread.CurrentThread to access current job working.
3.A Cross-Platform way like Net Standard.
Second: Example-1 (CrossPlatform-Working) My example not working, because Post and Send method in SynchronizationContext don't work
class Program
{
static void Main(string[] args)
{
SynchronizationContext contextThread1 = null;
SynchronizationContext contextThread2 = null;
Thread thread1, thread2 = null;
thread1 = new Thread(() =>
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
contextThread1 = SynchronizationContext.Current;
while (true)
{
Thread.Sleep(1000);
if (contextThread2 != null)
{
contextThread2.Post((state) =>
{
//Thread.CurrentThread == thread2 always false because the method is not runnig from thread 2
Console.WriteLine("call a method from thread 1 for thread 2 :" + (Thread.CurrentThread == thread2));
}, null);
}
}
});
thread1.IsBackground = true;
thread1.Start();
thread2 = new Thread(() =>
{
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
contextThread2 = SynchronizationContext.Current;
while (true)
{
Thread.Sleep(1000);
if (contextThread1 != null)
{
contextThread1.Post((state) =>
{
//Thread.CurrentThread == thread1 always false because the method is not runnig from thread 1
Console.WriteLine("call a method from thread 2 for thread 1 :"+(Thread.CurrentThread == thread1));
}, null);
}
}
});
thread2.IsBackground = true;
thread2.Start();
Console.ReadKey();
}
}
Example-2: (No Cross PLatform because Windowsbase.dll): this example works fine but this is not cross platform.
class Program
{
static void Main(string[] args)
{
Dispatcher contextThread1 = null;
Dispatcher contextThread2 = null;
Thread thread1, thread2 = null;
thread1 = new Thread(() =>
{
contextThread1 = Dispatcher.CurrentDispatcher;
Dispatcher.Run();
});
thread1.IsBackground = true;
thread1.Start();
thread2 = new Thread(() =>
{
contextThread2 = Dispatcher.CurrentDispatcher;
Dispatcher.Run();
});
thread2.IsBackground = true;
thread2.Start();
while (true)
{
Thread.Sleep(1000);
if (contextThread2 != null)
{
contextThread2.Invoke(new Action(() =>
{
//Thread.CurrentThread == thread2 always false because the method is not runnig from thread 2
Console.WriteLine("call a method from thread 1 for thread 2 :" + (Thread.CurrentThread == thread2));
}));
}
if (contextThread1 != null)
{
contextThread1.Invoke(new Action(() =>
{
Console.WriteLine("call a method from thread 2 for thread 1 :" + (Thread.CurrentThread == thread1));
}));
}
}
Console.ReadKey();
}
}
You should always use a tool these days to make your life easier where possible. In this case you should use Microsoft's Reactive Framework. Just NuGet "System.Reactive" and add using System.Reactive.Linq;.
Then you can do this:
void Main()
{
var thread1 = new EventLoopScheduler();
var thread2 = new EventLoopScheduler();
Action action = () => Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
action();
thread1.Schedule(action);
Thread.Sleep(1000);
thread2.Schedule(action);
Thread.Sleep(1000);
thread2.Schedule(() =>
{
action();
thread1.Schedule(action);
});
Thread.Sleep(1000);
action();
}
The kind of output I get is:
11
12
14
14
12
11
If you follow along with the code you can see it is correctly scheduling to each thread.
When you want to shut down just call .Dispose() on each EventLoopScheduler.

C# how do I disable a button thats running on the main thread?

I have looked everywhere for the answer and I thought it would be simple to find but apparently not. I've heard about invoke but I have no idea how to use it or what it is.
Here is my code:
public void Thread1(object sender, EventArgs e)
{
this.button1.Enabled = false;
this.textBox2.Clear();
this.textBox3.Clear();
this.textBox4.Clear();
this.textBox6.Text = "£" + "0";
//Generate 3 random numbers
Stopwatch timer = new Stopwatch();
timer.Start();
this.Refresh();
//This is only part of this function
}
private void button1_Click(object sender, EventArgs e)
{
ThreadStart threadStart = new ThreadStart(() => Thread1(sender, e));
Thread newThread = new Thread(threadStart);
newThread.Start();
}
In background threads, use Invoke() on WinForms components to execute code on the UI thread:
this.Invoke( () => {
this.button1.Enabled = true;
this.textBox2.Text = "whatever";
} );
Documentation: https://msdn.microsoft.com/en-us/library/a1hetckb.aspx

Multithreading in C# with Win.Forms control

I'm beginner in C#. And i have problem with threads when i using win.forms. My application freezes. What the problem with this code? I'm using microsoft example from msdn.
Here's my code:
delegate void SetTextCallback(object text);
private void WriteString(object text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(WriteString);
this.Invoke(d, new object[] { text });
}
else
{
for (int i = 0; i <= 1000; i++)
{
this.textBox1.Text = text.ToString();
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Thread th_1 = new Thread(WriteString);
Thread th_2 = new Thread(WriteString);
Thread th_3 = new Thread(WriteString);
Thread th_4 = new Thread(WriteString);
th_1.Priority = ThreadPriority.Highest; // самый высокий
th_2.Priority = ThreadPriority.BelowNormal; // выше среднего
th_3.Priority = ThreadPriority.Normal; // средний
th_4.Priority = ThreadPriority.Lowest; // низкий
th_1.Start("1");
th_2.Start("2");
th_3.Start("3");
th_4.Start("4");
th_1.Join();
th_2.Join();
th_3.Join();
th_4.Join();
}
There is a deadlock - UI thread is waiting for threads to complete with Thread.Join() while the worker threads are trying to send a message to UI using blocking Control.Invoke(). Replacing the Invoke in the thread code by BeginInvoke() will make the deadlock go away
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(WriteString);
// BeginInvoke posts message to UI thread asyncronously
this.BeginInvoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text.ToString();
}
It freezes because of the Join calls. Thread.Join() makes the current thread wait after another one is complete.

Measuring thread running time

public void Foo(IRB inR) {
Stopwatch sw = new Stopwatch();
sw.Start();
System.Threading.Thread theThread = new System.Threading.Thread(delegate() {
if (inR.Ready) {
inR.ABC();
while (!inR.Ready) { Thread.Sleep(100); }
}
mP.CP = false;
});
theThread.Name = "aaabbbccc";
theThread.Start();
}
So, I want use StopWatch measuring the time that "theThread" running. (Actually, I want to measure time from creating of this thread to end of thread.)
I already put stopwatch.start() where I want. But where should I put my stopwatch.stop()?
Thank you.
Why not put the stopwatch code in the thread itself? For example:
public class ThreadTimer
{
private readonly ThreadStart realWork;
public ThreadTimer(ThreadStart realWork)
{
this.realWork = realWork;
}
public void TimeAndExecute()
{
Stopwatch stopwatch = Stopwatch.StartNew();
try
{
realWork();
}
finally
{
stopwatch.Stop();
// Log or whatever here
}
}
}
Then:
ThreadStart work = delegate() {
if (inR.Ready) {
inR.ABC();
while (!inR.Ready) { Thread.Sleep(100); }
}
mP.CP = false;
};
ThreadTimer timer = new ThreadTimer(work);
Thread thread = new Thread(timer.TimeAndExecute);
thread.Start();
Can you put it at the end of your delegate?
You'd have to join the background thread with the running thread if you create the Stopwatch object as a variable local to your function. Or, you can create it outside the function to let the thread run without joining.
public void ConditionPlate(IRB inR)
{
Stopwatch sw = new Stopwatch();
sw.Start();
System.Threading.Thread theThread = new System.Threading.Thread(delegate()
{
if (inR.Ready)
{
inR.ABC();
while (!inR.Ready) { Thread.Sleep(100); }
}
mP.CP = false;
// ********************************
// This will stop the stopwatch.
// ********************************
sw.Stop();
});
theThread.Name = "aaabbbccc";
theThread.Start();
// Wait for the thread to stop (necessary if 'sw' is created here, locally)
theThread.Join();
// gets time required for creation of thread to thread completion.
var elapsed = sw.Elapsed;
}

Why does MSDN sample from Threading Tutorial crash?

From sample example 4 of MSDN "Threading Tutorial"
Following code errors out at the line commented with "---errors is here---".
What is wrong?
using System;
using System.Threading;
public class MutexSample
{
static Mutex gM1;
static Mutex gM2;
const int ITERS = 100;
static AutoResetEvent Event1 = new AutoResetEvent(false);
static AutoResetEvent Event2 = new AutoResetEvent(false);
static AutoResetEvent Event3 = new AutoResetEvent(false);
static AutoResetEvent Event4 = new AutoResetEvent(false);
public static void Main(String[] args)
{
Console.WriteLine("Mutex Sample ...");
// Create Mutex initialOwned, with name of "MyMutex".
gM1 = new Mutex(true, "MyMutex");
// Create Mutex initialOwned, with no name.
gM2 = new Mutex(true);
Console.WriteLine(" - Main Owns gM1 and gM2");
AutoResetEvent[] evs = new AutoResetEvent[4];
evs[0] = Event1; // Event for t1
evs[1] = Event2; // Event for t2
evs[2] = Event3; // Event for t3
evs[3] = Event4; // Event for t4
MutexSample tm = new MutexSample();
Thread thread1 = new Thread(new ThreadStart(tm.t1Start));
Thread thread2 = new Thread(new ThreadStart(tm.t2Start));
Thread thread3 = new Thread(new ThreadStart(tm.t3Start));
Thread thread4 = new Thread(new ThreadStart(tm.t4Start));
thread1.Start(); // Does Mutex.WaitAll(Mutex[] of gM1 and gM2)
thread2.Start(); // Does Mutex.WaitOne(Mutex gM1)
thread3.Start(); // Does Mutex.WaitAny(Mutex[] of gM1 and gM2)
thread4.Start(); // Does Mutex.WaitOne(Mutex gM2)
Thread.Sleep(2000);
Console.WriteLine(" - Main releases gM1");
gM1.ReleaseMutex(); // t2 and t3 will end and signal
Thread.Sleep(1000);
Console.WriteLine(" - Main releases gM2");
gM2.ReleaseMutex(); // t1 and t4 will end and signal
// Waiting until all four threads signal that they are done.
WaitHandle.WaitAll(evs);
Console.WriteLine("... Mutex Sample");
}
public void t1Start()
{
Console.WriteLine("t1Start started, Mutex.WaitAll(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1; // Create and load an array of Mutex for WaitAll call
gMs[1] = gM2;
Mutex.WaitAll(gMs); // Waits until both gM1 and gM2 are released
Thread.Sleep(2000);
Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[]) satisfied");
Event1.Set(); // AutoResetEvent.Set() flagging method is done
}
public void t2Start()
{
Console.WriteLine("t2Start started, gM1.WaitOne( )");
gM1.WaitOne(); // Waits until Mutex gM1 is released ---errors is here---
Console.WriteLine("t2Start finished, gM1.WaitOne( ) satisfied");
Event2.Set(); // AutoResetEvent.Set() flagging method is done
}
public void t3Start()
{
Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1; // Create and load an array of Mutex for WaitAny call
gMs[1] = gM2;
Mutex.WaitAny(gMs); // Waits until either Mutex is released
Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])");
Event3.Set(); // AutoResetEvent.Set() flagging method is done
}
public void t4Start()
{
Console.WriteLine("t4Start started, gM2.WaitOne( )");
gM2.WaitOne(); // Waits until Mutex gM2 is released
Console.WriteLine("t4Start finished, gM2.WaitOne( )");
Event4.Set(); // AutoResetEvent.Set() flagging method is done
}
}
After waiting on a Mutex you have to release it, using
Mutex.ReleaseMutex()
before the threads exits.
fixed t1start - t4start
public void t1Start()
{
Console.WriteLine("t1Start started, Mutex.WaitAll(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1; // Create and load an array of Mutex for WaitAll call
gMs[1] = gM2;
Mutex.WaitAll(gMs); // Waits until both gM1 and gM2 are released
Thread.Sleep(2000);
Console.WriteLine("t1Start finished, Mutex.WaitAll(Mutex[]) satisfied");
Event1.Set(); // AutoResetEvent.Set() flagging method is done
gM1.ReleaseMutex();
gM2.ReleaseMutex();
}
public void t2Start()
{
Console.WriteLine("t2Start started, gM1.WaitOne( )");
gM1.WaitOne(); // Waits until Mutex gM1 is released ---errors is here---
Console.WriteLine("t2Start finished, gM1.WaitOne( ) satisfied");
gM1.ReleaseMutex();
Event2.Set(); // AutoResetEvent.Set() flagging method is done
}
public void t3Start()
{
Console.WriteLine("t3Start started, Mutex.WaitAny(Mutex[])");
Mutex[] gMs = new Mutex[2];
gMs[0] = gM1; // Create and load an array of Mutex for WaitAny call
gMs[1] = gM2;
int result = Mutex.WaitAny(gMs); // Waits until either Mutex is released
gMs[result].ReleaseMutex();
Console.WriteLine("t3Start finished, Mutex.WaitAny(Mutex[])"); Event3.Set(); // AutoResetEvent.Set() flagging method is done
}
public void t4Start()
{
Console.WriteLine("t4Start started, gM2.WaitOne( )");
gM2.WaitOne(); // Waits until Mutex gM2 is released
Console.WriteLine("t4Start finished, gM2.WaitOne( )");
Event4.Set(); // AutoResetEvent.Set() flagging method is done
gM2.ReleaseMutex();
}

Categories

Resources