首页 新闻 搜索 专区 学院

winform中多线程,如何让线程执行的方法顺序执行

0
悬赏园豆:30 [已解决问题] 解决于 2015-02-10 17:39

我有3个主要的任务,被写成3个主方法,方法里面还会调用其他方法等。
 使用winfrom做的,因为三个方法执行都需要很长的时间,特别是第三个方法,可能需要很多天。
为了不让窗体卡死,我决定使用多线程,我已经解决了,跨线程访问出错的问题,也可以将单个方法,交给一个后台线程执行,但是我有三个方法,显然我都要交给后台线程去执行,但是我不管是用三个线程,还是一个线程,它的执行顺序都很混乱,用一个线程时,它先执行的是最后一个方法,用3个线程时它是跑来跑去,没有顺序(好像是同时执行)。
我需要严格按照Func1 ,Func2,Func3的顺序依次执行,因为后一个方法需要前一个方法生成的文件。这是必须的。


如果既使用多线程,还能让方法,按照一定顺序执行,有什么办法吗?求高手指导下。

我不用线程池技术,我全部用Thread,因为我需要运行很长时间。

荆棘人的主页 荆棘人 | 菜鸟二级 | 园豆:205
提问于:2015-02-04 17:08
< >
分享
最佳答案
-1

为了不让界面卡死, 而采用多线程, 我是醉了…… 线程是无序的, 你这种情况还不如不用。。。。

如果你非得要用, 你可以在Func2里面thread1.Join()方法, 让当前线程卡住等1线程完再继续。 以此类推,Func3里Join第2线程。 这样也就有序了。。。

还有一种方法, 设个全局的标记, 去判定这个全局标记的状态,  

PS: 骚年郎啊, 你这东西可以做个windows服务嘛。。。跑几天几夜的winform, 我真的是醉了!

收获园豆:10
问天何必 | 老鸟四级 |园豆:3301 | 2015-02-04 17:23

我勒个去, 我写了这么多, 楼上直接给代码了。。。。 

那我也给点代码:

  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完,重点========
           //继续干你的事;
            //....
        }                    

 

问天何必 | 园豆:3301 (老鸟四级) | 2015-02-04 17:28

@问天何必: 你的方法我感觉也很好,我感觉可以!我怎么就没想到呢?谢谢你!阿利亚多!

荆棘人 | 园豆:205 (菜鸟二级) | 2015-02-04 17:39

大哥,我也想过写成服务似乎很好,不过我不会写window服务。winform也只好简单的。半吊子程序员,培训出身,一年工作经验,事件,委托,反射都还没搞清楚……请原谅。

荆棘人 | 园豆:205 (菜鸟二级) | 2015-02-04 17:50

@荆棘人:你这样做 倒序执行就会有问题的哦 参考一下这个,如果可以用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!");
        }
    }
}
hirisw | 园豆:202 (菜鸟二级) | 2017-12-07 14:12
其他回答(5)
0

void method1()

{

...

method2();

}

void method2()

{

...

method3();

}

既然有顺序为什么要开三个线程 而不写在一起?

收获园豆:10
nicky0227 | 园豆:1069 (小虾三级) | 2015-02-04 17:14

按照你说的,我已经在修改,我先试一试。

支持(0) 反对(0) 荆棘人 | 园豆:205 (菜鸟二级) | 2015-02-04 17:29
1
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("一定 是第三个");
        }
    }
}
收获园豆:10
田麦成 | 园豆:1984 (小虾三级) | 2015-02-04 17:21

我感觉你的方法是可以的,学习新知识了,谢谢你!阿利亚多。

支持(0) 反对(0) 荆棘人 | 园豆:205 (菜鸟二级) | 2015-02-04 17:37

@荆棘人: 这种信号量的方式应该是比较好的方式。

支持(0) 反对(0) 幻天芒 | 园豆:36652 (高人七级) | 2015-02-04 21:48
0

既然是按顺序,还需要多线程吗?

上帝之城 | 园豆:2452 (老鸟四级) | 2015-02-04 19:26
0

靠写代码控制Thread执行顺序很容易造成代码啰嗦繁琐且极容易引发bug,用Task吧,task1.ContinueWith(task2).ContinueWith(task3)这种完全满足你的需求,而且代码优雅执行逻辑可控。

JeffWong | 园豆:2021 (老鸟四级) | 2015-02-05 10:13

谢谢你,豆子不够分!

支持(0) 反对(0) 荆棘人 | 园豆:205 (菜鸟二级) | 2015-02-10 17:42
0

http://www.cnblogs.com/hirisw/archive/2012/03/10/2388900.html

hirisw | 园豆:202 (菜鸟二级) | 2017-12-07 14:09
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册