(1) No need to pass parameters, and no need to return parameters
ThreadStart is a delegate, which is defined as void ThreadStart(), with no parameters and return value.
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 30; i++)
{
ThreadStart threadStart = new ThreadStart(Calculate);
Thread thread = new Thread(threadStart);
thread.Start();
}
Thread.Sleep(2000);
Console.Read();
}
public static void Calculate()
{
DateTime time = DateTime.Now;//Get the current time
Random ra = new Random();//Random number object
Thread.Sleep(ra.Next(10,100));//Sleep randomly for a period of time
Console.WriteLine(time.Minute + ":" + time.Millisecond);
}
}
(2) Need to pass a single parameter
The ParameterThreadStart delegate is defined as void ParameterizedThreadStart(object state), which has one parameter but no return value.
class Program
{
static void Main(string[] args)
{
for (int i = 0; i < 30; i++)
{
ParameterizedThreadStart tStart = new ParameterizedThreadStart(Calculate);
Thread thread = new Thread(tStart);
thread.Start(i*10+10);//Pass parameters
}
Thread.Sleep(2000);
Console.Read();
}
public static void Calculate(object arg)
{
Random ra = new Random();//Random number object
Thread.Sleep(ra.Next(10, 100));//Sleep randomly for a period of time
Console.WriteLine(arg);
}
}
(3) Use a special thread class (commonly used)
Using the thread class can have multiple parameters and multiple return values, very flexible!
class Program
{
static void Main(string[] args)
{
MyThread mt = new MyThread(100);
ThreadStart threadStart = new ThreadStart(mt.Calculate);
Thread thread = new Thread(threadStart);
thread.Start();
//Wait for the thread to end
while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(10);
}
Console.WriteLine(mt.Result);//Print the return value
Console.Read();
}
}
public class MyThread//Thread class
{
public int Parame { set; get; }//parameter
public int Result { set; get; }//return value
//Constructor
public MyThread(int parame)
{
this.Parame = parame;
}
// thread execution method
public void Calculate()
{
Random ra = new Random();//Random number object
Thread.Sleep(ra.Next(10, 100));//Sleep randomly for a period of time
Console.WriteLine(this.Parame);
this.Result = this.Parame * ra.Next(10, 100);
}
}
(4) Use anonymous methods (commonly used)
Starting a thread with an anonymous method can have multiple parameters and return values, and it's very convenient to use!
class Program
{
static void Main(string[] args)
{
int Parame = 100;//As a parameter
int Result = 0;//As the return value
// anonymous method
ThreadStart threadStart = new ThreadStart(delegate()
{
Random ra = new Random();//Random number object
Thread.Sleep(ra.Next(10, 100));//Sleep randomly for a period of time
Console.WriteLine(Parame);//Output parameters
Result = Parame * ra.Next(10, 100);//Calculate the return value
});
Thread thread = new Thread(threadStart);
thread.Start();//Multi-thread start anonymous method
//Wait for the thread to end
while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(10);
}
Console.WriteLine(Result);//Print the return value
Console.Read();
}
}
(5) Use delegate to open multi-threading (multi-threading in-depth)
1. Use the BeginInvoke and EndInvoke methods of the delegate (Delegate) to operate the thread
The BeginInvoke method can use a thread to execute the method pointed to by the delegate asynchronously. Then obtain the return value of the method through the EndInvoke method (the return value of the EndInvoke method is the return value of the called method), or determine that the method has been successfully called.
class Program
{
private delegate int NewTaskDelegate(int ms);
private static int newTask(int ms)
{
Console.WriteLine("Task Start");
Thread.Sleep(ms);
Random random = new Random();
int n = random.Next(10000);
Console.WriteLine("Task completed");
return n;
}
static void Main(string[] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
//EndInvoke method will be blocked for 2 seconds
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
Console.Read();
}
}
2. Use the IAsyncResult.IsCompleted property to determine whether the asynchronous call is complete
code show as below:
class Program
{
private delegate int NewTaskDelegate(int ms);
private static int newTask(int ms)
{
Console.WriteLine("Task Start");
Thread.Sleep(ms);
Random random = new Random();
int n = random.Next(10000);
Console.WriteLine("Task completed");
return n;
}
static void Main(string[] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
//Wait for the asynchronous execution to complete
while (!asyncResult.IsCompleted)
{
Console.Write("*");
Thread.Sleep(100);
}
// Since the asynchronous call has completed, EndInvoke will return the result immediately
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
Console.Read();
}
}
3. Use the WaitOne method to wait for the completion of the asynchronous method execution
The first parameter of WaitOne represents the number of milliseconds to wait. Within the specified time, the WaitOne method will wait until the asynchronous call is completed and a notification is sent, and the WaitOne method will return true. After waiting for the specified time, the asynchronous call has not been completed, and the WaitOne method returns false. If the specified time is 0, it means not waiting, and if it is -1, it means waiting forever until the asynchronous call is completed.
code show as below:
class Program
{
private delegate int NewTaskDelegate(int ms);
private static int newTask(int ms)
{
Console.WriteLine("Task Start");
Thread.Sleep(ms);
Random random = new Random();
int n = random.Next(10000);
Console.WriteLine("Task completed");
return n;
}
static void Main(string[] args)
{
NewTaskDelegate task = newTask;
IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);
//Wait for the asynchronous execution to complete
while (!asyncResult.AsyncWaitHandle.WaitOne(100, false))
{
Console.Write("*");
}
int result = task.EndInvoke(asyncResult);
Console.WriteLine(result);
Console.Read();
}
}
4. Use the callback method to return the result
It should be noted that "my.BeginInvoke(3,300, MethodCompleted, my)", the parameter passing method of the BeginInvoke method:
The first part (3,300) is the parameter of its delegate itself.
The penultimate parameter (MethodCompleted) is the callback method delegate type, which is the delegate of the callback method. This delegate has no return value and has a parameter of type IAsyncResult. When the method method is executed, the system will automatically call the MethodCompleted method.
The last parameter (my) needs to pass some value to the MethodCompleted method. Generally, the delegate of the called method can be passed. This value can be obtained using the IAsyncResult.AsyncState property.
code show as below:
class Program
{
private delegate int MyMethod(int second, int millisecond);
// thread execution method
private static int method(int second, int millisecond)
{
Console.WriteLine("Thread sleep" + (second * 1000 + millisecond) + "milliseconds");
Thread.Sleep(second * 1000 + millisecond);
Random random = new Random();
return random.Next(10000);
}
//callback method
private static void MethodCompleted(IAsyncResult asyncResult)
{
if (asyncResult == null || asyncResult.AsyncState == null)
{
Console.WriteLine("Callback failed!!!");
return;
}
int result = (asyncResult.AsyncState as MyMethod).EndInvoke(asyncResult);
Console.WriteLine("Task completed, result: " + result);
}
static void Main(string[] args)
{
MyMethod my = method;
IAsyncResult asyncResult = my.BeginInvoke(3,300, MethodCompleted, my);
Console.WriteLine("Task Start");
Console.Read();
}
}
5. BeginXXX and EndXXX methods of other components
There are also methods similar to BeginInvoke and EndInvoke in other. Net components, such as the BeginGetResponse and EndGetResponse methods of the System.Net.HttpWebRequest class. Its usage is similar to the BeginInvoke and EndInvoke methods of the delegate type, for example:
class Program
{
//Callback
private static void requestCompleted(IAsyncResult asyncResult)
{
if (asyncResult == null || asyncResult.AsyncState==null)
{
Console.WriteLine("Callback failed");
return;
}
HttpWebRequest hwr = asyncResult.AsyncState as HttpWebRequest;
HttpWebResponse response = (HttpWebResponse)hwr.EndGetResponse(asyncResult);
StreamReader sr = new StreamReader(response.GetResponseStream());
string str = sr.ReadToEnd();
Console.WriteLine("Return stream length: "+str.Length);
}
static void Main(string[] args)
{
HttpWebRequest request =
(HttpWebRequest)WebRequest.Create("http://www.baidu.com");
//async request
IAsyncResult asyncResult = request.BeginGetResponse(requestCompleted, request);
Console.WriteLine("Task Start");
Console.Read();
}
}