Consider the following example taken from HelloWorld Multithreaded C# app
using System;
using System.Threading;
class ThreadTest
{
static void Main()
{
Thread t = new Thread (WriteY); // Kick off a new thread
t.Start(); // running WriteY()
// Simultaneously, do something on the main thread.
for (int i = 0; i < 1000; i++) Console.Write ("x");
}
static void WriteY()
{
for (int i = 0; i < 1000; i++) Console.Write ("y");
}
}
is there a way to have a function like "static double WriteY (double a)" instead of "static void WriteY()" ?
I am not sure what you want to do with return value of Write method, but I think i get your intention and modified your code snippet to address what you looking for :
class ThreadTest
{
static void Main()
{
Task t = Task.Run(() => Write(5));
// Simultaneously, do something on the main thread.
for (int i = 0; i < 1000; i++) Console.Write ("x");
t.wait();
}
static double Write(double a)
{
for (int i = 0; i < 1000; i++) Console.Write("y");
return a;
}
}
Related
Is there a simple way to check if any threads are waiting for a specific ManualResetEvent
object to be set? It seems to me that the computer must be somehow keeping a queue of the
paused threads to restore later, so I'm just hoping to do the obvious and access
this list (just to check whether or not it is empty)...but I couldn't find a
method from looking at Microsoft's related Threading/WaitHandle/Monitor help pages.
Test code is below. I'd simply like to replace the uglyWaiters counter.
using System;
using System.Threading;
namespace demo
{
class Program
{
static void Main()
{
var gate = new ManualResetEvent(false);
int uglyWaiters = 0; // I want to stop using this variable and instead use something built into ManualResetEvent
new Thread(() =>
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("a" + i);
uglyWaiters++;
gate.WaitOne();
uglyWaiters--;
Thread.Sleep(400);
}
}).Start();
new Thread(() =>
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine("b" + i);
uglyWaiters++;
gate.WaitOne();
uglyWaiters--;
Thread.Sleep(500);
}
}).Start();
for (int count = 0; count < 15; count++)
{
Console.WriteLine(uglyWaiters + " threads waiting at t=" + count*230 + "ms");
gate.Set(); Thread.Sleep(30); gate.Reset();
Thread.Sleep(200);
}
Console.ReadLine();
}
}
}
Instead of printing o and -, I want to print the number of o and - on the console. However, I have no idea how to get how many times a loop spins in a thread before it gets switched to other threads.
If there are events something likes OnLeaving and OnEntering on a thread, I can get the number of spins in the given time slice. Unfortunately, I have no such events.
class Program
{
public const int N = 1000;
static void Main(string[] args)
{
ThreadStart ts = DoWork;
Thread t = new Thread(ts);
t.Start();
for (int x = 0; x < N; x++)
{
Console.Write('o');
}
t.Join();
}
private static void DoWork()
{
for (int x = 0; x < N; x++)
{
Console.Write('-');
}
}
}
Could you show me how to do this scenario?
To reiterate: AbhayDixit's comment gives you a cycle counter. You just need to add a locking mechanism and reset the counters after a context switch.
I have modified your code to include a cycle counter. Note that I have increased N significantly. Otherwise, one thread will just run through its 1000 iterations at once - because you no longer have a Write() instruction to slow it down.
class Program
{
public const int N = 1000000;
private static object _l = new object();
private static int _i = 0;
private static int _j = 0;
static void Main(string[] args)
{
ThreadStart ts = DoWork;
Thread t = new Thread(ts);
t.Start();
for (int x = 0; x < N; x++)
{
lock (_l)
{
// j-thread has run?
if (_j > 0)
{
// print and reset j
Console.Write("j{0} ", _j);
_j = 0;
}
_i++;
}
}
t.Join();
// print remaining cycles
// one of the threads will have run after the other has finished and
// hence not been printed and reset.
if (_i > 0)
Console.Write("i{0} ", _i);
if (_j > 0)
Console.Write("j{0} ", _j);
Console.ReadKey();
}
private static void DoWork()
{
for (int x = 0; x < N; x++)
{
lock (_l)
{
// i-thread has run?
if (_i > 0)
{
// print and reset i
Console.Write("i{0} ", _i);
_i = 0;
}
_j++;
}
}
}
}
I was trying to spawn certain number of threads. But when I pass arguments to the function the output is random. It chooses some values of variable 'i' for multiple times and ignores some. I am a newbie in C#. Please explain if I am doing anything wrong.
using System;
using System.Threading;
public class first
{
public static void tone(int i)
{
Console.WriteLine("Hi ! this is thread : {0} ",i);
Thread.Sleep(10);
}
public static void Main(String[] args)
{
int i;
for (i = 0; i < 10; i++)
{
Thread th1 = new Thread(()=>tone(i) );
th1.Start();
// Console.WriteLine(i);
}
Console.WriteLine("hey there!");
Console.ReadLine();
}
}
Because of closure:
Change your code to:
int i;
for (i = 0; i < 10; i++)
{
int j = i;
Thread th1 = new Thread(()=>tone(j) );
th1.Start();
// Console.WriteLine(i);
}
I have the following C# code snippet in which I have simulated my problem. In this program I have a Service function that call ReadRooms method.
Now I am calling the service method on different threads. I was expecting that both ServiceCall and ReadRooms method will fired equally but I am getting below result that is not correct.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
public static void ReadRooms(int i)
{
Console.WriteLine("Reading Room::" + i);
Thread.Sleep(2000);
}
public static void CallService(int i)
{
Console.WriteLine("ServiceCall::" + i);
ReadRooms(i);
}
static void Main(string[] args)
{
Thread[] ts = new Thread[4];
for (int i = 0; i < 4; i++)
{
ts[i] = new Thread(() =>
{
int temp = i;
CallService(temp);
});
ts[i].Start();
}
for (int i = 0; i < 4; i++)
{
ts[i].Join();
}
Console.WriteLine("done");
Console.Read();
}
}
}
You are still 'capturing the loop variable'. You are creating a temp but too late, when i is already captured.
Try this:
for (int i = 0; i < 4; i++)
{
int temp = i; // outside the lambda
ts[i] = new Thread(() =>
{
//int temp = i; // not here
CallService(temp);
});
ts[i].Start();
}
You should put this line
int temp = i;
before the Thread creation
for (int i = 0; i < 4; i++)
{
int temp = i;
ts[i] = new Thread(() => CallService(temp));
ts[i].Start();
}
This way you will create a local copy of i that will be used by the lambda expression.
Your thread action is closing over the variable i instead of its current value. You therefore have a race between the thread reading i and the increment in the for loop. You can pass it as a parameter instead:
ts[i] = new Thread(index =>
{
CallService((int)index);
});
ts[i].Start(i);
alternatively you can move the copy of temp to inside the loop instead of the thread action:
for (int i = 0; i < 4; i++)
{
int temp = i;
ts[i] = new Thread(() =>
{
CallService(temp);
});
ts[i].Start();
}
private void button1_Click(object sender, EventArgs e)
{
for (int i = 0; i < 15; i++)
{
Thread nova = new Thread(Method);
nova.Start();
}
listBox1.Items.Add("Some text");
}
private void Method()
{
for (int i = 0; i < 15; i++)
{
Console.WriteLine(i);
}
}
This code does write: Some text and then numbers 111222333.....
I would like that it writes 111122223333.... and then on the end Some text.
is it possible to do that with threads (parent thread wait for child threads)? or do i have to use something else?
You need to keep track of all the threads, and use Thread.Join on each one. This waits until the specified thread terminates, and then continues executing. Like this:
var threads = new List<Thread>();
for (int i = 0; i < 15; i++)
{
Thread nova = new Thread(Method);
nova.Start();
threads.Add(nova);
}
foreach (var thread in threads)
thread.Join();
listBox1.Items.Add("Some text");
I suggest to use TPL to get this done. You won't need to spawn so many threads. By default TPL will use thread pool for that:
using System;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
private const int TaskCount = 15;
static void Main(string[] args)
{
var tasks = new Task[TaskCount];
for (var index = 0; index < TaskCount; index++)
{
tasks[index] = Task.Factory.StartNew(Method);
}
Task.WaitAll(tasks);
Console.WriteLine("Some text");
}
private static void Method()
{
for (int i = 0; i < 15; i++)
{
Console.WriteLine(i);
}
}
}
}
You could have two threads, the 2nd one waiting on a signal to fire from the first.
private void Foo()
{
var signals = new List<ManualResetEvent>();
for (int i = 0; i < 15; i++)
{
var signal = new ManualResetEvent(false);
signals.Add(signal);
var thread = new Thread(() => { Method(); signal.Set(); });
thread.Start();
}
var completionTask = new Thread(() =>
{
WaitHandle.WaitAll(signals.ToArray());
CompletionWork();
});
completionTask.Start();
}
private void Method()
{
}
private void CompletionWork()
{
}
The better solution now with .Net 4.0 (and later) is to use Tasks, and invoke a method using ContinueWith
private void Foo()
{
var childThreads = new List<Task>();
for (int i = 0; i < 15; i++)
{
var task = new Task(Method);
task.Start();
childThreads.Add(task);
}
var completionTask = new Task(() =>
{
Task.WaitAll(childThreads.ToArray());
}).ContinueWith(t => CompletionWork());
}
private void Method()
{
}
private void CompletionWork()
{
}
The join answers also work, but require the containing thread to block. If you don't want the GUI to block, Spawn an additional thread around the 1st.
You can use thread.join to wait for threads to end. See http://www.dotnetperls.com/thread-join for an page on how to use it.