Task 多线程
Task 多线程简单好用,异步和同步线程方法,无返回值的委托用到Action,有返回值委托Func。
1 public static void TaskStart01()
2 {
3 Task task = new Task(() => Calculate(22));
4 Console.WriteLine($"Task Start 之前的状态{task.Status}"); //Created
5 task.Start();
6 Console.WriteLine($"Task Start 之前的状态{task.Status}"); //WaitingToRun
7
8 //Task.Run(Action action)将任务放在线程池队列,返回并启动一个Task
9 //.Net Framework 4.5后开始支持Task.Run
10 Task.Run(() => Calculate(23));
11
12 //线程需要长时间运行的话那就选择Task.Factory.StartNew,参数种类丰富
13 Task.Factory.StartNew(() => Calculate(23));
14 }
15
16 static void Calculate(int count)
17 {
18 int sum = 0;
19 for (int i = count; i > 0; i--)
20 {
21 sum += i;
22 Console.WriteLine($"最大值是{count},此时变量i 的值是{i}, 累加出来结果是 {sum}");
23 Thread.Sleep(200);
24 }
25 }
有返回值的Task
static void TaskWithResult()
{
Task<string> task = new Task<string>(() => TotaoSum());
task.Start();
// task.Wait();//等待 task 执行完
Task<string> task2 = Task.Run(() => TotaoSum());
Task<string> task3 = Task.Factory.StartNew(() => TotaoSum());
Console.WriteLine("主线程运行啦");
Console.WriteLine(task.Result);
Console.WriteLine(task2.Result);
Console.WriteLine(task3.Result);
Console.WriteLine("以上属性多线程并发,同时访问TotalSum 函数,属于异步,如果需要做的同步 用到task.wait()");
Console.ReadLine();
}
static string TotaoSum()
{
int sum = 0;
for (int i = 22; i > 0; i--)
{
sum += i;
Console.WriteLine($"当下坐标是 {i},当前线程Id {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(200);
}
return sum.ToString();
}
WinForm 中Button开启一个task,线程执行的时候,UI主线程假死,拖不动界面。
1 private void button3_Click(object sender, EventArgs e)
2 {
3
4 Task<int> task = Task.Run(() => CalculateWithCancel(23, cancelTokenSourece.Token));
5 //Task.Run(() => CalculateWithCancel(23, cancelTokenSourece.Token)); //还是因为有返回值 导致主线程阻塞
6 Console.WriteLine("这里是主线程输出");
7 }
8 private void button4_Click(object sender, EventArgs e)
9 {
10 if (cancelTokenSourece != null)
11 {
12 Console.WriteLine("点击取消按钮");
13 cancelTokenSourece.Cancel();
14 }
15 }
16 private int CalculateWithCancel(int count, CancellationToken token)
17 {
18 int sum = 0;
19 for (int i = count; i > 0; i--)
20 {
21 sum += i;
22 if (cancelTokenSourece.IsCancellationRequested)
23 {
24 Console.WriteLine("完哒,线程被取消了");
25 return -1;
26 }
27 Console.WriteLine($"当前线程id:{Thread.CurrentThread.ManagedThreadId},最大值是{count},此时变量i 的值是{i}, 累加出来结果是 {sum}");
28 Thread.Sleep(200);
29 }
30 Console.WriteLine("子线程执行完了");
31 return 200;
32 }
昨天界面还假死的,今天就奇迹般的治愈了。百思不得姐。
Task.Wait() 函数
static void TaskWait()
{
Console.WriteLine($"当下为主线程,当前线程Id {Thread.CurrentThread.ManagedThreadId}");
Task task = new Task(() => TotaoSumWait());
task.Start();
Task task1 = new Task(() => TotaoSumWait());
task1.Start();
Task.WaitAll(new Task[] { task, task1 });// task 子线程执行完毕,等待
Console.WriteLine($"看看是不是最后执行,当前线程Id {Thread.CurrentThread.ManagedThreadId}");
Console.ReadLine();
}
static void TotaoSumWait()
{
int sum = 0;
for (int i = 22; i > 0; i--)
{
sum += i;
Console.WriteLine($"当下坐标是 {i},当前线程Id {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(200);
}
}
Async 和 Await 的组合使用,线程想单独跑么,要和主线程同步的 。
static void TaskAsync()
{
Task<string> data = GetContentAsync(Environment.CurrentDirectory + @"/test.txt");
Console.WriteLine(data.Result);
Console.WriteLine("子线程结束,主线程登场");
Console.ReadLine();
}
//异步读取文件内容
async static Task<string> GetContentAsync(string filename)
{
FileStream fs = new FileStream(filename, FileMode.Open);
var bytes = new byte[fs.Length];
//ReadAync方法异步读取内容,不阻塞线程
Console.WriteLine("开始读取文件");
int len = await fs.ReadAsync(bytes, 0, bytes.Length);
string result = Encoding.UTF8.GetString(bytes);
return result;
}
常用的就这些个吧!!!
C#AutoResetEvent和ManualResetEvent的区别

浙公网安备 33010602011771号