新建一个Winfrom项目,加入下面代码:
-
using System;
-
using System.Collections.Generic;
-
using System.Threading;
-
using System.Threading.Tasks;
-
using System.Windows.Forms;
-
-
namespace 线程2
-
{
-
public
partial
class
Form1 :
Form
-
{
-
public Form1()
-
{
-
InitializeComponent();
-
}
-
-
private void Form1_Load(object sender, EventArgs e)
-
{
-
Task task1 =
new Task(() =>
-
{
-
Thread.Sleep(
400);
-
Console.WriteLine(
"task1");
-
});
-
Task task2 =
new Task(() =>
-
{
-
Thread.Sleep(
300);
-
Console.WriteLine(
"task2");
-
});
-
Task task3 =
new Task(() =>
-
{
-
Thread.Sleep(
200);
-
Console.WriteLine(
"task3");
-
});
-
Task task4 =
new Task(() =>
-
{
-
Thread.Sleep(
100);
-
Console.WriteLine(
"task4");
-
});
-
task1.Start();
-
task2.Start();
-
task3.Start();
-
task4.Start();
-
}
-
}
-
}
运行:
由于延时不同,最先执行的Task1,反而最后一个执行完,那么如果要求从任务1,一直执行到任务4,怎么写呢?
代码:
-
using System;
-
using System.Collections.Generic;
-
using System.Threading;
-
using System.Threading.Tasks;
-
using System.Windows.Forms;
-
-
namespace 线程
2
-
{
-
public partial
class Form1 : Form
-
{
-
public Form1()
-
{
-
InitializeComponent();
-
}
-
-
private List<Task> TaskList =
new List<Task>();
-
-
private void Form1_Load(object sender, EventArgs e)
-
{
-
Task task1 =
new Task(() =>
-
{
-
Thread.Sleep(
400);
-
Console.WriteLine(
"task1");
-
});
-
Task task2 =
new Task(() =>
-
{
-
Thread.Sleep(
300);
-
Console.WriteLine(
"task2");
-
});
-
Task task3 =
new Task(() =>
-
{
-
Thread.Sleep(
200);
-
Console.WriteLine(
"task3");
-
});
-
Task task4 =
new Task(() =>
-
{
-
Thread.Sleep(
100);
-
Console.WriteLine(
"task4");
-
});
-
-
TaskList.Add(task1);
-
TaskList.Add(task2);
-
TaskList.Add(task3);
-
TaskList.Add(task4);
-
-
foreach (Task task in TaskList)
-
{
-
task.Start();
-
task.Wait();
-
}
-
}
-
}
-
}
运行:
用上面的方法虽然有效,但会阻塞主线程,导致winfrom界面卡住,无法操作,下面就用异步的方法解决问题
代码:
-
using System;
-
using System.Collections.Generic;
-
using System.Threading;
-
using System.Threading.Tasks;
-
using System.Windows.Forms;
-
-
namespace 线程2
-
{
-
public
partial
class
Form1 :
Form
-
{
-
public Form1()
-
{
-
InitializeComponent();
-
}
-
-
-
private List<Task> TaskList =
new List<Task>();
-
-
private void Form1_Load(object sender, EventArgs e)
-
{
-
-
}
-
-
private void Button_Calculate_Click(object sender, EventArgs e)
-
{
-
Task task1 =
new Task(
async () =>
-
{
-
await Task.Delay(TimeSpan.FromSeconds(
4));
-
Console.WriteLine(
"task1");
-
});
-
Task task2 =
new Task(
async () =>
-
{
-
await Task.Delay(TimeSpan.FromSeconds(
3));
-
Console.WriteLine(
"task2");
-
});
-
Task task3 =
new Task(
async () =>
-
{
-
await Task.Delay(TimeSpan.FromSeconds(
2));
-
Console.WriteLine(
"task3");
-
});
-
Task task4 =
new Task(
async () =>
-
{
-
await Task.Delay(TimeSpan.FromSeconds(
1));
-
Console.WriteLine(
"task4");
-
});
-
-
TaskList.Add(task1);
-
TaskList.Add(task2);
-
TaskList.Add(task3);
-
TaskList.Add(task4);
-
-
foreach (Task task
in TaskList)
-
{
-
task.Start();
-
task.Wait();
-
}
-
}
-
}
-
}
运行:
用异步方式虽然界面不会卡住,但另一个问题来了,task.wait()方法似乎没有效果。里面的任务队列依然没有按顺序来执行。
经过一段时间的研究,后面我终于找到方法了,用下面的方法既不会卡住UI,也会按照队列来执行,虽然写法不是特别好,读者可以按下面方法自己封装了。
-
private void Test()
-
{
-
Task.Run(() =>
-
{
-
Task t1 =
new Task(() => {
-
Thread.Sleep(
2000);
-
Console.WriteLine(
"t1");
-
num =
1;
-
});
-
t1.Start();
-
t1.Wait();
-
Task t2 =
new Task(() => {
-
Thread.Sleep(
1000);
-
Console.WriteLine(
"t2");
-
num =
3;
-
});
-
t2.Start();
-
t2.Wait();
-
Console.WriteLine(
"线程执行完毕");
-
});
-
}
运行:
也可以这样写:
-
private async void Test()
-
{
-
await Task.Run(
async () =>
-
{
-
await Task.Delay(
4000);
-
Trace.WriteLine(
"第1个线程执行");
-
});
-
await Task.Run(
async () =>
-
{
-
await Task.Delay(
3000);
-
Trace.WriteLine(
"第2个线程执行");
-
});
-
await Task.Run(
async () =>
-
{
-
await Task.Delay(
2000);
-
Trace.WriteLine(
"第3个线程执行");
-
});
-
}
运行:
对现有代码进行封装:
-
using System;
-
using System.Collections.Generic;
-
using System.Threading.Tasks;
-
-
namespace
Utils
-
{
-
public
class
TaskQueue
-
{
-
/// <summary>
-
/// 任务列表
-
/// </summary>
-
private List<Task> TaskList =
null;
-
/// <summary>
-
/// 是否在执行任务中
-
/// </summary>
-
private
bool isPerformTask =
false;
-
/// <summary>
-
/// 执行完任务的回调
-
/// </summary>
-
public Action CallBack =
null;
-
-
-
private
static TaskQueue _instance =
null;
-
public
static TaskQueue Instance
-
{
-
get
-
{
-
if (_instance ==
null)
-
_instance =
new TaskQueue();
-
return _instance;
-
}
-
}
-
-
/// <summary>
-
/// 添加任务
-
/// </summary>
-
/// <param name="task"></param>
-
public void AddTask(Task task)
-
{
-
if (isPerformTask)
-
{
-
Console.WriteLine(
"[TaskQueue]任务正在执行中,此时不能做赋值操作");
-
return;
-
}
-
-
if (task !=
null)
-
{
-
TaskList.Add(task);
-
}
-
}
-
-
/// <summary>
-
/// 执行任务
-
/// </summary>
-
public void PerformTask()
-
{
-
if (isPerformTask)
-
{
-
Console.WriteLine(
"[TaskQueue]任务正在执行中,不可重复调用");
-
return;
-
}
-
if (TaskList ==
null || TaskList.Count ==
0)
-
{
-
Console.WriteLine(
"[TaskQueue]任务列表为空");
-
return;
-
}
-
-
Task.Run(() =>
-
{
-
isPerformTask =
true;
-
-
foreach (Task item
in TaskList)
-
{
-
item.Start();
-
item.Wait();
-
}
-
-
TaskList.Clear();
-
isPerformTask =
false;
-
-
if (CallBack !=
null) CallBack();
-
});
-
}
-
-
private TaskQueue()
-
{
-
TaskList =
new List<Task>();
-
}
-
}
-
}
调用:
-
Task task1 =
new Task(() =>
-
{
-
Thread.Sleep(
1000);
-
Console.WriteLine(
"t1");
-
});
-
Task task2 =
new Task(() =>
-
{
-
Thread.Sleep(
2000);
-
Console.WriteLine(
"t2");
-
});
-
Task task3 =
new Task(() =>
-
{
-
Console.WriteLine(
"t3");
-
});
-
Action callback = () =>
-
{
-
Console.WriteLine(
"所有任务执行完成");
-
};
-
TaskQueue.Instance.AddTask(task1);
-
TaskQueue.Instance.AddTask(task2);
-
TaskQueue.Instance.AddTask(task3);
-
TaskQueue.Instance.CallBack = callback;
-
TaskQueue.Instance.PerformTask();
运行:
如果你这个帖子对你有用,欢迎给我点赞 + 留言,谢谢
end
转载:https://blog.csdn.net/qq_38693757/article/details/117361771
查看评论