Multiple threads calling same method in C# - c#

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();
}

Related

How to remove duplicate object array in c# (without using other function or library)

i was tried to code my self a no duplicate object array function.
But it not working.
Somehow it print all the object element
May i know where i am doing it wrong ? I was so confuse why it is not working.
This is my code
using System;
using System.Text;
using System.Linq;
namespace MyApp
{
internal class Program
{
static void Main(string[] args)
{
object[] mix_arr = new object[8];
mix_arr[0] = 25;
mix_arr[1] = "Anna";
mix_arr[2] = false;
mix_arr[3] = 25;
mix_arr[4] = System.DateTime.Now;
mix_arr[5] = 112.22;
mix_arr[6] = "Anna";
mix_arr[7] = false;
object[] unique_arr = new object[8];
bool clone = false; // this bool is to check duplicate
int k = 0; // increment the unique_ arr index
for (int i = 0; i < 8; i++)
{
clone = false;
// clone will always set to false
for (int j = 0; j < i; j++)
{
if(unique_arr[j] == mix_arr[i])
{
// if found 2 object element are the same, set clone true
clone = true;
break;
}
}
if (clone == false)
{
// if no duplicate entry
unique_arr[k++] = mix_arr[i];
}
}
for (int i = 0; i < 8; i++)
{
Console.Write("{0} ",mix_arr[i]);
}
Console.WriteLine("");
}
}
}

HelloWorld Multithreaded C# app with double input and output

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;
}
}

Who is waiting for a ManualResetEvent?

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();
}
}
}

Why am I getting unexpected output when spawning threads?

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);
}

Parallel.For Loop with Thread-Local Variables

I have a C# ASP.NET MVC project.
I am basically running a simulation (with an option to cancel) and collating the results.
I need to use multi-threading as I could run a million or more simulations at at time.
My code is like this:
public class MyClass
{
private ConcurrentBag<StuffResult> StuffResults { get; set; }
private bool CancellationRequested { get; set; }
public void DoAlotOfStuff(int numberOfStuffToDo)
{
var cancellationTokenSource = new CancellationTokenSource();
var options = new ParallelOptions { CancellationToken = cancellationTokenSource.Token };
Task.Factory.StartNew(() =>
{
if (CancellationRequested) cancellationTokenSource.Cancel();
});
try
{
Parallel.For(0, numberOfStuffToDo, options, a =>
{
options.CancellationToken.ThrowIfCancellationRequested();
var class1 = new Class1();
var class2 = new Class2();
var class3 = new Class3();
var class4 = new Class4(class1, class2, class3);
var result = class4.DoStuff();
StuffResults.Add(result);
});
}
catch (OperationCanceledException e)
{
//handle exception
}
}
}
Question: How can I avoid instantiating a new Class1, Class2, Class3, and Class4 object for each iteration? I read this msdn article but I don't understand it. Perhaps 1 of each object per thread.
It look safe enough to me...
If the classes have some kind of state involved with them then I don't know if you can avoid instantiating them. If not, you might be able to declare the classes outside the loop or make the DoStuff method static so you don't need an instantiated class at all.
I would do it like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ParallelTest
{
class Program
{
static AutoResetEvent autoReset = new AutoResetEvent(false);
static void Main(string[] args)
{
// since this is an async method it will be run in a different thread
DoSomething();
// wait for the async method to signal the main thread
autoReset.WaitOne();
Console.WriteLine("done");
}
async static void DoSomething()
{
// create some common data
const int count = 50000;
const int factor = 3;
// create some tasks
var task1 = Task.Run(() =>
{
int x = 0;
for (int i = 0; i < count * 2; ++i)
{
x += i + factor * 3;
Console.WriteLine("task1: " + i + factor * 3);
}
return x;
});
var task2 = Task.Run(() =>
{
int x = 0;
for (int i = 0; i < count * 2; ++i)
{
x += i + factor * 4;
Console.WriteLine("task2: " + i + factor * 4);
}
return x;
});
var task3 = Task.Run(() =>
{
int x = 0;
for (int i = 0; i < count * 2; ++i)
{
x += i + factor * 5;
Console.WriteLine("task3: " + i + factor * 5);
}
return x;
});
// create a resulttask which will run all the tasks in parallel
var resultTask = Task.WhenAll(task1, task2, task3);
// start the task and wait till it finishes
var results = await resultTask;
// display the results
for (int i = 0; i < results.Length; ++i)
{
Console.WriteLine("result" + i + ": " + results[i]);
}
// signal main thread
autoReset.Set();
}
}
}

Categories