我有3个主要的任务,被写成3个主方法,方法里面还会调用其他方法等。
使用winfrom做的,因为三个方法执行都需要很长的时间,特别是第三个方法,可能需要很多天。
为了不让窗体卡死,我决定使用多线程,我已经解决了,跨线程访问出错的问题,也可以将单个方法,交给一个后台线程执行,但是我有三个方法,显然我都要交给后台线程去执行,但是我不管是用三个线程,还是一个线程,它的执行顺序都很混乱,用一个线程时,它先执行的是最后一个方法,用3个线程时它是跑来跑去,没有顺序(好像是同时执行)。
我需要严格按照Func1 ,Func2,Func3的顺序依次执行,因为后一个方法需要前一个方法生成的文件。这是必须的。
如果既使用多线程,还能让方法,按照一定顺序执行,有什么办法吗?求高手指导下。
我不用线程池技术,我全部用Thread,因为我需要运行很长时间。
为了不让界面卡死, 而采用多线程, 我是醉了…… 线程是无序的, 你这种情况还不如不用。。。。
如果你非得要用, 你可以在Func2里面thread1.Join()方法, 让当前线程卡住等1线程完再继续。 以此类推,Func3里Join第2线程。 这样也就有序了。。。
还有一种方法, 设个全局的标记, 去判定这个全局标记的状态,
PS: 骚年郎啊, 你这东西可以做个windows服务嘛。。。跑几天几夜的winform, 我真的是醉了!
我勒个去, 我写了这么多, 楼上直接给代码了。。。。
那我也给点代码:
Private Thread th1; //全局变量线程1 Private Thread th2; //全局变量线程2 Private Thread th3; //全局变量线程3 private void button1_Click(object sender, EventArgs e) { th1 = new Thread(new ThreadStart(Func1)); th1.Start(); th2 = new Thread(new ThreadStart(Func2)); th2.Start(); th3 = new Thread(new ThreadStart(Func3)); th3.Start(); } private void Func1() { //...干你的事; } private void Func2() { th1.Join(); //卡下等1完。 重点======== //继续干你的事; //.... } private void Func3() { th2.Join(); //卡下等2完,重点======== //继续干你的事; //.... }
@问天何必: 你的方法我感觉也很好,我感觉可以!我怎么就没想到呢?谢谢你!阿利亚多!
大哥,我也想过写成服务似乎很好,不过我不会写window服务。winform也只好简单的。半吊子程序员,培训出身,一年工作经验,事件,委托,反射都还没搞清楚……请原谅。
@荆棘人:你这样做 倒序执行就会有问题的哦 参考一下这个,如果可以用Task当然更简单
using System; using System.Collections.Generic; using System.Threading; namespace _3vjDemos { public class OrderedExecuteThread { public OrderedExecuteThread ThreadFront { get; set; } public Action<Object> ActionDoing { get; set; } public OrderedExecuteThread() { } public Thread Thread { get; set; } public bool IsCurrentExcuted { get; set; } public bool IsCurrentStarted { get; set; } public bool IsCurrentDealt { get; set; } public int OrderedIndex { get; set; } public void ExecuteThread(Object obj) { try { IsCurrentDealt = true; if (ActionDoing != null) { ActionDoing.Invoke(obj); } Thread.Sleep(new Random().Next(0, 200) * 100);//DoSomeThing while (true) { if ((ThreadFront == null || ThreadFront.Thread == null || ThreadFront.IsCurrentExcuted) && !this.IsCurrentExcuted&&!IsCurrentStarted) { Thread.Start(this.OrderedIndex); this.IsCurrentStarted = true; } Thread.Sleep(50); if (!Thread.IsAlive && IsCurrentStarted) { this.IsCurrentExcuted = true; break; } } } catch (Exception ex) { Console.WriteLine("Thread " + this.OrderedIndex.ToString() + " exit by " + ex.Message); } } } public class OrderedExecuteThreads { public List<OrderedExecuteThread> OrderedThreads { get; set; } public void ExecuteThreads() { for (int i = OrderedThreads.Count - 1; i >= 0; i--) { var thread = OrderedThreads[i]; if (!thread.IsCurrentDealt) { Thread tTest = new Thread(thread.ExecuteThread); tTest.Start(null); } } } public static void OrderedExecuteThreadTest(int threadCount) { List<OrderedExecuteThread> orderedThreads = new List<OrderedExecuteThread>(); List<Thread> threads = new List<Thread>(); for (int i = 0; i < threadCount; i++) { Thread thread = new Thread(new ParameterizedThreadStart(PrintExecuteThreadIndex)); threads.Add(thread); } for (int i = 0; i < threadCount; i++) { OrderedExecuteThread orderThread = new OrderedExecuteThread(); orderThread.Thread = threads[i]; orderThread.OrderedIndex = i; orderedThreads.Add(orderThread); } for (int i = 0; i < threadCount; i++) { OrderedExecuteThread orderThread = orderedThreads[i]; if (i > 0) { orderThread.ThreadFront = orderedThreads[i - 1]; } } OrderedExecuteThreads executeThreads = new OrderedExecuteThreads(); executeThreads.OrderedThreads = orderedThreads; executeThreads.ExecuteThreads(); } private static void PrintExecuteThreadIndex(object index) { Console.WriteLine("Thread " + index.ToString() + " executed!"); } } }
void method1()
{
...
method2();
}
void method2()
{
...
method3();
}
既然有顺序为什么要开三个线程 而不写在一起?
按照你说的,我已经在修改,我先试一试。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; namespace ConsoleApplication2 { class Program { static AutoResetEvent flag1 = new AutoResetEvent(false); static AutoResetEvent flag2 = new AutoResetEvent(false); static AutoResetEvent flag3 = new AutoResetEvent(false); static void Main(string[] args) { Thread th1 = new Thread(new ThreadStart(A)); th1.Start(); Thread th2 = new Thread(new ThreadStart(B)); th2.Start(); Thread th3 = new Thread(new ThreadStart(C)); th3.Start(); //开放第一道关卡 flag1.Set(); } static void A() { //在这里静侯关卡打开 flag1.WaitOne(); Console.WriteLine("一定 是第一个"); //开放第二道关卡 flag2.Set(); } static void B() { //在这里静侯关卡打开 flag2.WaitOne(); Console.WriteLine("一定 是第二个"); //开放第三道关卡 flag3.Set(); } static void C() { //在这里静侯关卡打开 flag3.WaitOne(); Console.WriteLine("一定 是第三个"); } } }
我感觉你的方法是可以的,学习新知识了,谢谢你!阿利亚多。
@荆棘人: 这种信号量的方式应该是比较好的方式。
既然是按顺序,还需要多线程吗?
靠写代码控制Thread执行顺序很容易造成代码啰嗦繁琐且极容易引发bug,用Task吧,task1.ContinueWith(task2).ContinueWith(task3)这种完全满足你的需求,而且代码优雅执行逻辑可控。
谢谢你,豆子不够分!
http://www.cnblogs.com/hirisw/archive/2012/03/10/2388900.html