Multi threading; pass object to another object - c#

I need to pass an object to another object. I know I have to pass c to t1. How do I do this
Thread t = new Thread(t1);
t.Start();
private static void t1(Class1 c)
{
while (c.process_done == false)
{
Console.Write(".");
Thread.Sleep(1000);
}
}

Ok guys, everybody is missing the point the object is being used outside the thread as well. This way, it must be synchronized to avoid cross-thread exceptions.
So, the solution would be something like this:
//This is your MAIN thread
Thread t = new Thread(new ParameterizedThreadStart(t1));
t.Start(new Class1());
//...
lock(c)
{
c.magic_is_done = true;
}
//...
public static void t1(Class1 c)
{
//this is your SECOND thread
bool stop = false;
do
{
Console.Write(".");
Thread.Sleep(1000);
lock(c)
{
stop = c.magic_is_done;
}
while(!stop)
}
}
Hope this helps.
Regards

You could simply do:
Thread t = new Thread(new ParameterizedThreadStart(t1));
t.Start(new Class1());
public static void t1(object c)
{
Class1 class1 = (Class1)c;
...
}
MSDN: ParameterizedThreadStart Delegate
Or even better:
Thread thread = new Thread(() => t1(new Class1()));
public static void t1(Class1 c)
{
// no need to cast the object here.
...
}
This approach permits multiple arguments and does not require you to cast the object to the desired class/struct.

private static void DoSomething()
{
Class1 whatYouWant = new Class1();
Thread thread = new Thread(DoSomethingAsync);
thread.Start(whatYouWant);
}
private static void DoSomethingAsync(object parameter)
{
Class1 whatYouWant = parameter as Class1;
}

Related

Can we invoke method outside the thread block by any technique in C#? so that we can use same thread method to invoke other methods as well.?

e.g.
Here in this example, if I want to start thread on method M1 this way,
Purpose is I need to call M2, M3 on same thread method to avoid repeated code.
Is this possible in C#?
static void Main()
{
if(StartThread() => M1()) //I want to invoke Method M1 from here like this
{
return;
}
}
private void StartThread()
{
var t = new Thread(() => M1()); //I dont want to invoke Method M1 from here
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}
private static void M1()
{
throw new NotImplementedException();
}
Just use a delegate (e.g. an Action) and pass it to StartThread:
static void Main()
{
if(StartThread(() => M1()))
return;
}
private void StartThread(Action a)
{
var t = new Thread(() => a());
t.SetApartmentState(ApartmentState.STA);
t.Start();
t.Join();
}
private static void M1()
{
throw new NotImplementedException();
}

Using thread.sleep in lock section C#

I create an example about thread,
I know that use lock could avoid thread suspending at critical section, but I have two questions.
1.Why my program get stuck if I use Thread.Sleep?
In this example, I add sleep to two thread.
Because I wish the console output more slowly, so I can easily see if there's anything wrong.
But if I use Thread.Sleep() then this program will get stuck!
2.What situation should I use Thread.Sleep?
Thanks for your kind response, have a nice day.
class MyThreadExample
{
private static int count1 = 0;
private static int count2 = 0;
Thread t1;
Thread t2;
public MyThreadExample() {
t1 = new Thread(new ThreadStart(increment));
t2 = new Thread(new ThreadStart(checkequal));
}
public static void Main() {
MyThreadExample mt = new MyThreadExample();
mt.t1.Start();
mt.t2.Start();
}
void increment()
{
lock (this)
{
while (true)
{
count1++; count2++;
//Thread.Sleep(0); stuck when use Sleep!
}
}
}
void checkequal()
{
lock (this)
{
while (true)
{
if (count1 == count2)
Console.WriteLine("Synchronize");
else
Console.WriteLine("unSynchronize");
// Thread.Sleep(0);
}
}
}
}
Please take a look at these following codes. Never use lock(this), instead use lock(syncObj) because you have better control over it. Lock only the critical section (ex.: only variable) and dont lock the whole while loop. In method Main, add something to wait at the end "Console.Read()", otherwise, your application is dead. This one works with or without Thread.Sleep. In your code above, your thread will enter "Increment" or "Checkequal" and the lock will never release. Thats why, it works only on Increment or Checkequal and never both.
internal class MyThreadExample
{
private static int m_Count1;
private static int m_Count2;
private readonly object m_SyncObj = new object();
private readonly Thread m_T1;
private readonly Thread m_T2;
public MyThreadExample()
{
m_T1 = new Thread(Increment) {IsBackground = true};
m_T2 = new Thread(Checkequal) {IsBackground = true};
}
public static void Main()
{
var mt = new MyThreadExample();
mt.m_T1.Start();
mt.m_T2.Start();
Console.Read();
}
private void Increment()
{
while (true)
{
lock (m_SyncObj)
{
m_Count1++;
m_Count2++;
}
Thread.Sleep(1000); //stuck when use Sleep!
}
}
private void Checkequal()
{
while (true)
{
lock (m_SyncObj)
{
Console.WriteLine(m_Count1 == m_Count2 ? "Synchronize" : "unSynchronize");
}
Thread.Sleep(1000);
}
}
}
Thread is a little bit old style. If you are a beginner of .NET and using .NET 4.5 or above, then use Task. Much better. All new multithreading in .NET are based on Task, like async await:
public static void Main()
{
var mt = new MyThreadExample();
Task.Run(() => { mt.Increment(); });
Task.Run(() => { mt.Checkequal(); });
Console.Read();
}

how to create\start a thread with parameters

How do I use ThreadStart to create\start a thread with method parameters.
private void GenerateData(Type Method){
ThreadStart tStart = null;
tStart = new ThreadStart(Method);
Thread t = new Thread(tStart);
t.Start();
}
private void DoWork{
//code processing here
}
// I want to call thread like this
private void rundata(){
GenerateData(Dowork);
}
It sounds like you might just want:
private void GenerateData(ThreadStart method)
{
Thread thread = new ThreadStart(method);
thread.Start();
}
You could then certainly have:
private void DoWork()
{
...
}
private void RunData()
{
GenerateData(DoWork);
}
... although given how trivial GenerateData is, I'm not sure it's really worth it... you could just have:
private void RunData()
{
new Thread(DoWork).Start();
}
instead.

Passing a parameter to a thread

I have a problem using threads. There is a class like this:
public class MyThread
{
public void Thread1(int a)
{
for (int i = 0; i < 1000000; i++)
{
j++;
for (int i1 = 0; i1 < 1000; i1++)
{
j++;
}
}
MessageBox.Show("Done From Class");
}
}
and I use this below code for using it:
private void button1_Click(object sender, EventArgs e)
{
MyThread thr = new MyThread();
Thread tid1 = new Thread(new ThreadStart(thr.Thread1));
tid1.Start();
MessageBox.Show("Done");
}
I get error because of Thread1 Parameter (int a),
there isn't any problem when I haven't got any parameter.
How can I fix it?
A preferred method is the first one as you can pass multiple parameters to your method without having to cast to object all the time.
Thread t= new Thread(() => thr.Thread1(yourparameter));
t.Start();
Alternatively, you need to use parameterised thread as you are passing parameter to thread. you can also do
Thread t = new Thread (new ParameterizedThreadStart(thr.Thread1));
t.Start (yourparameter);
ofcourse your parameter has to be of object type for second example.
Threads accept a single object parameter:
public void Thread1(object a1)
{
int a = (int)a1;
...
}
Pass it like this:
Thread t = new Thread(Thread1);
t.Start(100);
You don't normally need to build delegates. Doing new ThreadStart(...) is normally useless from C# 2.0 .
Another (common) solution is to put Thread1 in another object:
public class MyThread
{
public int A;
public void Thread1()
{
// you can use this.A from here
}
}
var myt = new MyThread();
myt.A = 100;
var t = new Thread(myt.Thread1)
t.Start();
This because delegates have a reference to the containing object of the method. Clearly in this way you lose access to the caller's object... But then you could do:
public class MyThread
{
public int A;
public CallerType ParentThis;
public void Thread1()
{
// you can use this.A from here
// You can use ParentThis.Something to access the caller
}
}
var myt = new MyThread();
myt.A = 100;
myt.ParentThis = this;
var t = new Thread(myt.Thread1)
t.Start();
A final common method is to use closures, as suggested by Ehsan Ullah (the example with the () =>)

How to create a thread and parse a parameter in C# 2.0

I have an method Process(Progressbar) in class Blacklist
i tried to use this :
Thread thread = new Thread(() => Blacklist.Process(pgImportProcess));
it occurs an error
C# 3.0 language Feature
So how can i create a thread and parse progressbar as a parameter?
Thank in advance
have you tried:
void Invoker(){
ParameterizedThreadStart pts = Start;
Thread thread = new Thread(pts);
thread.Start(new object());
}
public void Start(object o)
{
//do stuff
}
You can't access a UI object from a different thread than it was created on. Every Control has an Invoke method that will execute a delegate on the UI thread. For example if you need to update your progress bars progress:
progressBar.Invoke(new Action() { () => progressBar.Value = updateValue; });
So you just need to use the Thread constructor that takes a ParameterizedThreadStart delegate.
Thread thread = new Thread(StartProcess);
thread.Start(pgImportProcess);
...
private static void StartProcess(object progressBar) {
Blacklist.Process((ProgressBar)progressBar);
}
Can you create a class to passing your parameter like
public class Sample
{
object _value;
public Sample(object value)
{
this._value = value;
}
public void Do()
{
// dosomething
// Invoke the Process(value)
}
}
And then
Sample p = new Sample("your parameter : Progressbar");
new Thread(new ThreadStart(p.Do)).Start();

Categories

Resources