问高手一个C#多线程打印Queue队列

这个程序运行时候会有问题,跪求高手给我看下我希望达到以下两个效果1.点击“打印队列”按钮,开始运行,运行完毕后提示完毕2.让程序可以正常完美运行这个不能改为单线程,输入框... 这个程序运行时候会有问题,跪求高手给我看下
我希望达到以下两个效果

1.点击“打印队列”按钮,开始运行,运行完毕后提示完毕
2.让程序可以正常完美运行
这个不能改为单线程,输入框是输入线程数目的
源代码为百度网盘链接,谢谢
http://pan.baidu.com/share/link?shareid=3246648033&uk=2905214979
展开
 我来答
哲事姓无
2013-08-24 · TA获得超过1176个赞
知道小有建树答主
回答量:903
采纳率:100%
帮助的人:429万
展开全部

主要有2个问题。

1. 线程函数中GetData没有机制获取有无数据,所以会一直循环

2.  因为是多线程操作所以操作strTest时加上线程锁

主要修改如下三个函数即可


        private void button1_Click(object sender, EventArgs e)
        {
            var rad = new Random(); //实例化随机数产生

            lock (strTest) // <<-- 有多线程对数组进行操作,所以需要加锁
            {
                for (var i = 0; i < 1000; i++)
                {
                    strTest.Enqueue(rad.Next(100, 10000).ToString());
                }
            }
        }

        /// <summary>
        ///     线程工作的函数
        /// </summary>
        public void ThreadWork()
        {
            while (true)
            {
                string data;
                if (!GetData(out data))
                {
                    // 没数据,退出线程
                    setLog("OK");
                    return;
                }

                setLog(data);
                Thread.Sleep(1);
                
            }
        }

        // 对函数进行修改,当没有数据时返回false,让线程函数可以知道什么时候退出
        private bool GetData(out string data)
        {
            lock (strTest) //<<-- 有多线程对数组进行操作,所以需要加锁
            {
                if (strTest.Count == 0)
                {
                    data = null;
                    return false; //<-- 没有数据了,返回false
                }
                else
                {
                    data = strTest.Dequeue();
                    return true; // <-- 还有数据返回 true
                }
            }
        }
更多追问追答
追问
十分感谢,有个问题,比如我开10个线程,最后运行完毕后会输出
.......
OK --- 2013-08-24 20:39:18
......
会连续输出 10个OK,我希望只能输出1个OK,或者messagebox提示“完毕”
我应该怎么修改呢 ,在测试过程中,这个问题也一直困扰这我
感激不尽
追答

将所有线程都保存在一个数组中。然后开始一个检测线程,在线程中循环检测是否所有线程都中止了,如果都中止了,则相应的操作

        private void button2_Click(object sender, EventArgs e)
        {
            var threads = new List<Thread>();

            for (var i = 0; i < Convert.ToInt32(textBox1.Text); i++)
            {
                thread1 = new Thread(ThreadWork) {IsBackground = true}; //线程
                thread1.Start();

                threads.Add(thread1);// <-- 将所有线程对象加入一个数组中
            }

            // 启动一个线程,定时检测是否所有线程都已经结束了, 为了方便,这里使用了匿名函数
            ThreadPool.QueueUserWorkItem((param) =>
                {

                    while (true)
                    {
                        var findThread = threads.FindAll(thread => thread.IsAlive);
                        if (findThread.Count == 0)
                            break;

                        Thread.Sleep(300);
                    }

                    setLog("OK");
                });
        }

上面使用了检测循环休眠再检测的的流程,为了提高效率可以考虑使用线程事件 

还有一个使用计数器的方案,字数有限制,完整代码贴不下,需要的话你再问一次

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式