I'm trying to run a clock on the console application of C#. It should be pretty straight forward s=using threads and stopwatch, but somehow i cant start the thread.. here's the code:
public static void showBoard()
{
for(int i = 0 ; i< 40 ; i++)
{
for (int j = 0 ;j<40 ; j++)
{
Console.Write(board[i, j]);
}
Console.Write('\n');
}
Thread t = new Thread(Timer);
}
public static void Timer()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
while (true)
{
Console.SetCursorPosition(45, 1);
Console.Write(stopwatch.Elapsed.ToString());
}
}
Function Timer dont even start the excution, kindly tell me what am i doing wrong.
you forgot something
t.Start();
Threads need to be started explicitly, otherwise they don't run.
You need to start it with
t.Start();
see http://msdn.microsoft.com/en-us/library/a9fyxz7d(v=vs.110).aspx
You need to explicitly start a thread.
Use t.Start() ;
or
Do this
Thread t = new Thread(Timer).Start() ;
Check the following links if you need further info:-
http://msdn.microsoft.com/en-us/library/aa645740%28v=vs.71%29.aspx
http://www.codeproject.com/Articles/6678/Introduction-to-Threads-in-C
http://www.albahari.info/threading/threading.pdf
You need to add...
t.Start
...to start your thread.
You have created object of thread class, and now you have to start the thread, which you can do use the Start() method.
Thread t = new Thread(Timer);
t.Start();
Related
In the below program why the t.join functionality is not working. It will continue to type character O on the screen even when i have specified it to wait for the another thread to complete.
class Program
{
bool done;
static void Main(string[] args)
{
Thread t = new Thread(() => Go('U'));
for (int i = 0; i < 1000; i++)
{
Console.Write('O');
Thread.Sleep(500);
}
t.Start();
t.Join();
Console.WriteLine("Thread t has ended!");
Console.Read();
}
static void Go(char p)
{
for (int i = 0; i < 1000; i++)
{
Console.Write(p);
Thread.Sleep(500);
}
}
}
You never started the second thread - you're printing out Os, but you only start the second thread after you're done with that (in about eight minutes).
Move the t.Start(); before the loop, and it should work the way you expect it to work.
Don't guess around with multi-threading - it's incredibly easy to get subtly wrong. Learn what a thread is, what does Join do, and how to use multiple threads safely. Otherwise, you'll have a lot of fun debugging issues that are near impossible to reproduce and fix :)
I am relatively green to proper threading, I have this, it's modified for simplicity but it is essentially the same thing:
//Global:
N=2
bool[] mySwitches;
//In my main:
mySwitches = new bool[N];
for (int i = 0; i < N; i++)
{
ThreadList.Add(new Thread(() => Worker(i)));
ThreadList[i].Start();
}
//Outside of main:
Private Void Worker(int num)
{
while(true)
{
if (mySwitches[num]) //error happes here because num is equal to N, how?
{
//do something
}
}
}
As shown above, somehow a worker thread gets a value of num=N, I expect it to only reach N-1.
I know that i will get incremented after the Worker is created, is i somehow getting passed by reference instead of value?
I tried to fix the issue by putting a test before my while loop to return if num=N, but even with this provision I get the same error. This leads me to believe that num is incremented somehow after the thread starts.
I fixed this issue by putting a Sleep(20) directly after ThreadList[i].Start(), but I don't really like using Sleep, and it's clear I don't know how this threading scenario actually works.
Can anyone shed any light on this?
i is captured by its reference. Change your code as
for (int i = 0; i < N; i++)
{
var thInx = i;
ThreadList.Add(new Thread(() => Worker(thInx)));
ThreadList[thInx].Start();
}
For more info: http://csharpindepth.com/articles/chapter5/closures.aspx
I have a parallel algorithm which I have some barrier issues with. Before y'all scream "search" I can say I have looked at available posts and links, and I have followed the instructions for a barrier with Monitor.Wait and Monitor.PulseAll, but my issue is that all threads except the last one created (and initiated) is reached by the PulseAll from my main thread. Here are how the basic layout of the code is:
public static object signal = new object(); //This one is located as class variable, not in the method
public void RunAlgorithm(List<City> cities){
List<Thread> localThreads = new List<Thread>();
object[] temp = //some parameters here
for(int i = 0; i < numOfCitiesToCheck; i++){
Thread newThread = new Thread((o) => DoWork(o as object[]));
newThread.IsBackground = true;
newThread.Priority = ThreadPriority.AboveNormal;
newThread.Start(temp as object);
localThreads.Add(newThread);
}
//All threads initiated, now we pulse all
lock(signal){
Monitor.PulseAll(signal);
}
int counter = 0;
while(true){
if(counter == localThreads.Count){ break; }
localThreads[counter].Join();
counter++;
}
}
That's what done by the main thread (removed a few uneccessary pieces) and as stated before the main thread will always get stuck in the Join() on the last thread in the list.
This is how the method of the threads look like:
private void DoWork(object[] arguments){
lock(signal){
Monitor.Wait(signal);
}
GoDoWork(arguments);
}
Are there any other barriers I can use for this type of signaling? All I want is to let the main thread signal all threads at the same time so that they start at the same time. I want them to start at the same time inorder to have as close parallel as possible (I measure running time for the algorithm and a few other things). Is there any part of my barrier or code that is flawed (with the barrier I mean)? I tried running an instance with fewer threads and it still get stuck on the last one, I don't know why it is. I have confirmed by via VS debug that the last thread is sleeping (all other threads are !isAlive, while the last one isAlive = true).
Any help appreciated!
I managed to solve it using the Barrier class. Many thanks to Damien_The_Unbeliever! Still can't believe I haven't heard of it before.
public Barrier barrier = new barrier(1);
public void RunAlgorithm(List<City> cities){
List<Thread> localThreads = new List<Thread>();
object[] temp = //some parameters here
for(int i = 0; i < numOfCitiesToCheck; i++){
barrier.AddParticipant();
Thread newThread = new Thread((o) => DoWork(o as object[]));
newThread.IsBackground = true;
newThread.Priority = ThreadPriority.AboveNormal;
newThread.Start(temp as object);
localThreads.Add(newThread);
}
barrier.SignalAndWait();
int counter = 0;
while(true){
if(counter == localThreads.Count){ break; }
localThreads[counter].Join();
counter++;
}
}
private void DoWork(object[] arguments){
barrier.SignalAndWait();
GoDoWork(arguments);
}
static int i = 0;
static void Main()
{
ThreadTest tt = new ThreadTest();
new Thread(tt.Incr).Start();
tt.I();
tt.I2();
}
void Incr()
{
for(int x = 0; x < 3; x++)
{
Console.WriteLine(i);
i++;
}
}
void I()
{
while(i <= 3)
{
if(i==3)
break;
Console.WriteLine("Value of i in I:{0}",i);
}
}
void I2()
{
Console.WriteLine("\t\tFinally i is:{0}\n\n",i);
}
I have run this piece of code about a few hundred times now and find that I2 always executes last. Why does this happen? May be a few hundred times is not enough to see the true unpredictability of threads?
Output of 11 runs
Well, I2() is the last method in Main() and it is not threaded in any way.
So what's the question, why the thread finishes earlier?
That's because I2() is run after I() and the while-loop in I() effectively waits for the thread to finish first.
The method I2 will always be executed last. This has nothing to do with threads.
static void Main()
{
ThreadTest tt = new ThreadTest();
new Thread(tt.Incr).Start();
tt.I(); // This will be executed first
tt.I2(); // This will be executed last
}
The flow of the newly started thread and the current thread is not synchronized, but the current thread will continiue its operation in a synchronous fashion executing statements in the order as the appear. In this case I() will be called before I2().
I'm running the following code to start my threads, but they don't start as intended. For some reason, some of the threads start with the same objects (and some don't even start). If I try to debug, they start just fine (extra delay added by me clicking F10 to step through the code).
These are the functions in my forms app:
private void startWorkerThreads()
{
int numThreads = config.getAllItems().Count;
int i = 0;
foreach (ConfigurationItem tmpItem in config.getAllItems())
{
i++;
var t = new Thread(() => WorkerThread(tmpItem, i));
t.Start();
//return t;
}
}
private void WorkerThread(ConfigurationItem cfgItem, int mul)
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(10*mul);
}
this.Invoke((ThreadStart)delegate()
{
this.textBox1.Text += "Thread " + cfgItem.name + " Complete!\r\n";
this.textBox1.SelectionStart = textBox1.Text.Length;
this.textBox1.ScrollToCaret();
});
}
Anyone able to help me out?
Starting a thread doesn't really start the thread. Instead it schedules it for execution. I.e. at some point it will get to run when it is scheduled. Scheduling threads is a complex topic and an implementation detail of the OS, so your code should not expect a certain scheduling.
You're also capturing variables in your lambda. Please see this post (there is a section on Captured Variables) for the problems associated with doing that.
You just run into the (be me called) lambda error.
You provide the ConfigurationItem from the foreach loop directly. This leads to the fact, that all your threads get the same item (the last one).
To get this to work you have to create a reference for each item and apply this to each thread:
foreach (ConfigurationItem tmpItem in config.getAllItems())
{
i++;
var currentI = i;
var currentItem = tmpItem;
var t = new Thread(() => WorkerThread(currentItem, currentI));
t.Start();
//return t;
}
And you should also consider using a ThreadPool.
MSDN Description about how to use the ThreadPool
Short summary of differences here on SO
The problem seems to be there : () => WorkerThread(tmpItem, i)
I'm not used to Func<> but it seems to work like anonymous delegates in .NET 2.0. Thus, you may have a reference to the arguments of the WorkerThread() method. Hence, their values are retrieved later (when the thread actually runs).
In this case, you may already be at the next iteration of your main thread...
Try this instead :
var t = new Thread(new ParametrizedThreadStart(WorkerThread));
t.Start(new { ConfigurationItem = tmpItem, Index = i } );
[EDIT] Other implementation. More flexible if you need to pass new parameters to the thread in the future.
private void startWorkerThreads()
{
int numThreads = config.getAllItems().Count;
int i = 0;
foreach (ConfigurationItem tmpItem in config.getAllItems())
{
i++;
var wt = new WorkerThread(tmpItem, i);
wt.Start();
//return t;
}
}
private class WorkerThread
{
private ConfigurationItem _cfgItem;
private int _mul;
private Thread _thread;
public WorkerThread(ConfigurationItem cfgItem, int mul) {
_cfgItem = cfgItem;
_mul = mul;
}
public void Start()
{
_thread = new Thread(Run);
_thread.Start();
}
private void Run()
{
for (int i = 0; i < 100; i++)
{
Thread.Sleep(10 * _mul);
}
this.Invoke((ThreadStart)delegate()
{
this.textBox1.Text += "Thread " + _cfgItem.name + " Complete!\r\n";
this.textBox1.SelectionStart = textBox1.Text.Length;
this.textBox1.ScrollToCaret();
});
}
}
Do you really need to spawn threads manually (which is a rather expensive task) ? You could try to switch to the ThreadPool instead.
You can't assume that the threads will run in the same order they were called, unless you force it, and cause a dependency between them.
So the real question is - what is your goal ?
I think that the error is somewhere else. Here are some hints to help you debug :
Give a name containing to each thread, and display the thread name instead of the config item name :
this.textBox1.Text += "Thread " + Thread.Current.Name + " Complete!\r\n";
Display the content of config.getAllItems(), may be that some items has the same name (duplicated)
===========
Here are some additional information about multi threading with winforms:
dont create new Thread directly, use the ThreadPool instead :
ThreadPool.QueueUserWorkItem(state => { WorkerThread(tmpItem, i); });
If you really want to creat your threads, use this.BeginInvoke instead of this.Invoke your worker thread will finish sooner => less concurrent thread => better global performance
don't call Thread.Sleep in a loop, just do a big sleep: Thread.Sleep(10*mul*100);
I hope that this will help you.
Thanks to all of you!
I just implemented the threadpool, and that worked like a charm - with the added bonus of not spawning too many threads at once.
I'll have a look at the other solutions, too, but this time around the threadpool will save me from having to manually check for bozos with too many configs ;)