110,538
社区成员
发帖
与我相关
我的任务
分享
string[] tasks = new string[100];
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
tasks[i] = "任务" + (i + 1);//加载模拟的任务 实际业务当中有很多代码 这里只是模拟
}
}
//声明线程数组
Thread[] workThreads = new Thread[10];
public void DoWork(object ParObject)
{
int ThreadIndex = (int)ParObject;
for (int i = ThreadIndex; i < ThreadIndex + 10; i++)
{
// 取i下表
Console.WriteLine("线程" + workThreads[ThreadIndex].Name + "正在执行任务" + tasks[i]);//
Thread.Sleep(10);
}
//如果此方法退出了,那么这个线程也就退出了
}
private void buttonStart_Click(object sender, EventArgs e)
{
this.buttonStart.Enabled = false;
//循环创建并启动线程执行
for (int i = 0; i < workThreads.Length; i++)
{
if (workThreads[i] == null)
{
//如果线程不存在,则创建
workThreads[i] = new Thread(new ParameterizedThreadStart(DoWork));
workThreads[i].Name = i.ToString();
workThreads[i].Start(i);
}
else
{
//已经存在,如果没有运行,则启动
if (workThreads[i].ThreadState == ThreadState.Aborted || workThreads[i].ThreadState == ThreadState.Stopped)
{
workThreads[i] = new Thread(new ParameterizedThreadStart(DoWork));
workThreads[i].Name = i.ToString();
workThreads[i].Start(i);
}
else
{
workThreads[i].Start();
}
}
}
}
线程0正在执行任务任务1
线程1正在执行任务任务2
线程2正在执行任务任务3
线程3正在执行任务任务4
线程4正在执行任务任务5
线程5正在执行任务任务6
线程6正在执行任务任务7
线程7正在执行任务任务8
线程8正在执行任务任务9
线程9正在执行任务任务10
线程1正在执行任务任务3
线程0正在执行任务任务2
线程3正在执行任务任务5
线程2正在执行任务任务4
线程4正在执行任务任务6
线程6正在执行任务任务8
线程5正在执行任务任务7
线程7正在执行任务任务9
线程8正在执行任务任务10
线程9正在执行任务任务11
线程1正在执行任务任务4
线程3正在执行任务任务6
线程0正在执行任务任务3
线程2正在执行任务任务5
线程4正在执行任务任务7
线程5正在执行任务任务8
线程6正在执行任务任务9
线程7正在执行任务任务10
线程8正在执行任务任务11
线程9正在执行任务任务12
static string[] tasks;
static int index;
static void DoIt()
{
for (; ; )
{
string task;
lock (tasks)
{
if (index >= tasks.Length) //所有任务都完成了
return;
task = tasks[index++];
}
var tid = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("正在执行{0}_线程id={1}", task, tid);
Thread.Sleep(rnd.Next(5000)); //随机阻塞一会儿
Console.WriteLine("{0}结束", task);
}
}
static Random rnd = new Random();
tasks = new string[100];
for (int i = 0; i < 100; i++)
{
tasks[i] = "任务" + (i + 1);//加载模拟的任务 实际业务当中有很多代码 这里只是模拟
}
for (var i = 0; i < 10; i++)
new Thread(h => DoIt()).Start();
基本上,看看它的运行结果就知道,一个任务可以“提前”在哪个线程上执行,不能想当然地预先分配,而应该在运行中自动却分配。
这是算法本身的重点。static string[] tasks;
static int index;
static void DoIt()
{
begin:
string task;
lock (tasks)
{
if (index >= tasks.Length) //所有任务都完成了
return;
task = tasks[index++];
}
var tid = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("正在执行{0}_线程id={1}", task, tid);
Thread.Sleep(rnd.Next(5000)); //随机阻塞一会儿
Console.WriteLine("{0}结束", task);
goto begin;
}
static Random rnd = new Random();
调用它是tasks = new string[100];
for (int i = 0; i < 100; i++)
tasks[i] = "任务" + (i + 1);//加载模拟的任务 实际业务当中有很多代码 这里只是模拟
for (var i = 0; i < 10; i++)
ThreadPool.QueueUserWorkItem(h => DoIt());
这里唯一的技术就在于:使用 lock 来进行线程同步,仅需要同步 index++ 这一条语句而已!!
不过这种代码写的也太多了,如果你需要写大量这类代码(而不是偶尔写一个小练习),这种代码太丑、太繁琐、太不优雅了。
List<string> lst = new List<string>();
Action<string> action = DoWork2;
for (int i = 0; i < 100; i++)
{
lst.Add("任务" + (i + 1));
}
Worker work = new Worker(action);
work.Run(10,lst);
报错啊拉登
“System.NotSupportedException”类型的未经处理的异常在 mscorlib.dll 中发生
其他信息: 不支持一个 STA 线程上针对多个句柄的 WaitAll。[/quote]
。。。你这东西用在哪个地方了? Parallel.For(0, '//数组开始的编号.
ThMax, '//最大线程数.
Sub(StepId) '//步长
For I As Integer = StepId To Files.Length - 1 Step ThMax
.....
Next
)
List<string> lst = new List<string>();
Action<string> action = DoWork2;
for (int i = 0; i < 100; i++)
{
lst.Add("任务" + (i + 1));
}
Worker work = new Worker(action);
work.Run(10,lst);
报错啊拉登
“System.NotSupportedException”类型的未经处理的异常在 mscorlib.dll 中发生
其他信息: 不支持一个 STA 线程上针对多个句柄的 WaitAll。Parallel.For(0, 10, i =>
{
});
一句搞定……内部判断i的值,然后每个i对应不同的处理片段string[] tasks = new string[100];
for (int i = 0; i < 100; i++)
{
tasks[i] = "任务" + (i + 1);//加载模拟的任务 实际业务当中有很多代码 这里只是模拟
}
var q = from x in tasks.AsParallel().WithDegreeOfParallelism(10)
select DoIt(x);
Console.WriteLine("总共用了{0}个线程执行了{1}个任务!", q.Distinct().Count(), tasks.Count());
static Random rnd = new Random();
static int DoIt(string task)
{
var tid = Thread.CurrentThread.ManagedThreadId;
Console.WriteLine("正在执行{0}_线程id={1}", task, tid);
Thread.Sleep(rnd.Next(1000));
Console.WriteLine("{0}结束", task);
return tid;
}
只有一条 PLinq 语句就能写完了,何必整天纠结那些有 bug 的代码?