Sending Parameters to the Function called by a thread in C#? - c#

Sending Parameters to the Function called by a thread in C#,
this is my code:
myThread = new Thread(new ThreadStart(myfunc));
myThread.Start(i);
public void myfunc(int i)
{
...
}
I get error:
No overload for 'installDrivers' matches delegate
'system.Threading.ThredStart'

You can use a ParameterizedThreadStart.
Thread myThread = new Thread(new ParameterizedThreadStart(myfunc));
myThread.Start(i);
And your function
public void myfunc(object i)
{
int myInt = Convert.ToInt32(i);
}

Another option, utilizing lambdas makes it easy to call functions with any number of parameters, it also avoids the rather nasty conversion from object in the one parameter case:
int paramA = 1;
string paramB = "foo";
var myThread = new Thread(() => SomeFunc(paramA, paramB));
myThread.Start();
public void SomeFunc(int paramA, string paramB)
{
// Do something...
}

use this:
myThread = new Thread(new ParameterizedThreadStart(myfunc));
myThread.Start(i);
public void myfunc(object i) {... }
it might be usefull for your issue

Unless you are using C# < 2.0, you don't need to create a delegate. You can let the compiler implicitly create it for you.
myThread = new Thread(myfunc);
myThread.Start(i);
public void myfunc(object i)
{
int i2 = (int)i; // if i is an int
}
but note that the Thread constructor accepts only two types of delegates: one that is parameterless (ThreadStart) and one that accepts an object parameter (ParameterizedThreadStart). So here we are using the second one.

Related

Return a value from Thread

I see the class Thread has 4 constructors:
public Thread(ParameterizedThreadStart start);
public Thread(ThreadStart start);
public Thread(ParameterizedThreadStart start, int maxStackSize);
public Thread(ThreadStart start, int maxStackSize);
ParameterizedThreadStart and ThreadStart are delegate like this:
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
What if I want to create thread start function that return int, for example?
I see that the constructor is good only if i want return void.
You can use the Task Parallel Library which allows you to have a return value. If you actually want a new thread to be allocated, you can use the right overload of Task.Factory.StartNew:
public int DoSomething() { return 42; }
public async Task FooAsync()
{
int value = await Task.Factory.StartNew(
() => DoSomething(), TaskCreationOptions.LongRunning);
}
If you don't actually need the new thread allocation, and can use a thread-pool thread, then using Task.Run is simpler and better:
public async Task FooAsync()
{
int value = await Task.Run(() => DoSomething());
}
Edit:
If for some odd reason you really want to use the Thread class, you can do this by closing over a variable and passing it to a delegate pass to Thread.Start and rely on the side-effect created once the thread starts running:
var x = 5;
var thread = new Thread(() =>
{
var x = DoSomething();
});
thread.Start();
thread.Join(); // This will synchronously block the thread.
Console.WriteLine(x);
Though I would definitely try to avoid this if you can use the TPL.
You can use:
public void StartThread()
{
ParameterizedThreadStart pts = new ParameterizedThreadStart(this.DoWork);
Thread th = new Thread(pts);
int i =5;
th.Start(i);
}
public void DoWork(object data)
{
Console.WriteLine("I got data='{0}'", data);
}
or shorter
Thread th = new Thread(this.DoWork);
It is possible by creating the return value from the thread. Then you should take this variable by using a lambda expression. Assign to this variable a your "return" value from the worker thread and then it is necessary to wait till thread ends from the parent thread.
int value = 5; // a variable to store the return value
var thread = new Thread(() =>
{
value = 10; // Assign value to the return variable
});
thread.Start();
thread.Join();
Console.WriteLine(value); // use your variable to show in parent thread

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 () =>)

Multi threading; pass object to another object

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

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

.NET Threading - Quick question

What should I put instead of the "SomeType" in the below function?
Delegate seems to be wrong here..
public static void StartThread(SomeType target)
{
ThreadStart tstart = new ThreadStart(target);
Thread thread = new Thread(tstart);
thread.Start();
}
EDIT: I'm not looking for alternative ways to write this.
Try the System.Action type.
Here my test code:
static void Main(string[] args)
{
StartThread(() => Console.WriteLine("Hello World!"));
Console.ReadKey();
}
public static void StartThread(Action target)
{
ThreadStart tstart = new ThreadStart(target);
Thread thread = new Thread(tstart);
thread.Start();
}
You should have the ThreadStart as the argument instead of trying to initialize it within the method.
I think there will be no Sometype, as you are calling some function that will be threaded. Isn't so?
Like
Thread t = new Thread(new ThreadStart(function_name_here));
t.start();
and
void function_name_here()
{
Blah blah
}
FYI there is no return type but VOID.
Replace SomeType with System.Threading.ThreadStart or System.Threading.ParameterizedThreadStart.

Categories

Resources