读书人

求有项目心得的给点思路, 多线程,多台

发布时间: 2012-07-31 12:33:47 作者: rapoo

求有项目经验的给点思路, 多线程,多台网络打印机 循环打印任务 分不够还可以加 也可以有偿提供相关代码~~祝大家节日快乐.
最近在做个后厨打印的东西 要求是不断循环从数据库表里取出需要打印的任务 根据发送到各个打印机 如果打印机有什么情况主界面即时响应






我设想的大概思路是这样的 先对打印机 做了个类

C# code
public class Printer{        public string Name { get; set; } //打印机名称        public int Connecttime { get; set; } //超时时间        public string IP { get; set; } //打印机IP        public string Status{get;set;} //打印机状态 需要更新回主界面        public bool Open(){} //打开打印机        public bool Close(){} //关闭打印机        public bool Write(string strdata){} //打印机写内容} 



然后主界面里初始化时先初始化所有打印机 开启线程
C# code
  List<Printer> printers = new List<Printer>();        private void Form1_Load(object sender, EventArgs e)        {         // 另外有一张表维护了所有打印机的信息             printers.Add(xxxx);         //          // 然后针对每个打印机开个线程          foreach (Printer p in printers) //循环所有打印机            {               //这里创建线程             }                   } 

====================================


现在问题来了. 因为要定时去数据库里提取需要打印的数据 比如每3秒就抓取需要打印的数据 该怎么抓呢 谁负责抓呢

我的想法
1 主界面负责循环抓取所有打印任务 再分配给 各个打印线程 这样好像只要读取一次数据库 但是怎么根据IP分配给打印机的线程呢.

2 打印机的子线程负责自己每隔3秒循环,根据自己的IP 到数据库取相应的打印记录(where ip =this.ip) 好处是互相不干扰. 缺点好像是 如果10台打印机 读取数据库就要30次 线程工作也是要同时循环



感觉是第1种相对好一些 但是问题就是 如何能有任务的时候激活线程呢 比如 192.168.1.118 没有打印任务的时候就暂停或者休眠状态, 主线程给任务的时候就激活线程工作 工作完成通知主线程 , 还有就是如果打印机的线程正在进行打印任务了怎么办 主线程如何把任务再加进去..

还有就是主线程3秒抓任务 如果任务还没来的及完成 比如打印机卡了超过3秒正在打印了 新的任务又来了 而且可能和旧的任务重复冲突了

头都大了 还有个问题就是 打印机线程 如果状态改变了 如何通知到主线程? 是不是主线程每3秒循环取数的时候顺便扫描下各个线程的状态?


如果谁做过类似的 可以有偿提供相关代码 PM我 谢谢
















[解决办法]
第二种情况,你可以在每个子线程中维护一个任务列表,这样就不会冲突了,从列表中拿任务,而且这种情况也可以用于第一种方法,主线程给子线程分配任务,任务先保存到子线程列表
[解决办法]
我觉得吧,弄个取打印任务的线程负责准备打印任务,把取到的打印任务丢到队列里面去,打印线程共享一个打印队列,做好线程同步,一个打印任务所有的打印机都打印完成以后就移出队列,打印线程发现队列为空了以后就进入休眠状态
[解决办法]
忽然觉得这个挺好玩,瞎弄了个给你参考
C# code
class Program    {        /// <summary>        /// 打印任务管理类        /// </summary>        public class JobManager        {                         public delegate void JobHasGotDel(object sender, JobManagerEventArgs e);//取到打印任务委托            public event JobHasGotDel JobHasGot;//取到打印任务事件            private int _printtimes = 5;//打印机数量            public void StartGetJob(int printtimes)            {                this._printtimes = printtimes;                Thread getjobthread = new Thread(new ParameterizedThreadStart(GetJobProc));                getjobthread.Start();            }            private void GetJobProc(object obj)//取打印任务线程            {                while (true)                {                    Random ran = new Random();                    int rantime = ran.Next(5000);                    Thread.Sleep(rantime);//模拟取打印任务时间消耗                    jobqueue.Enqueue(new PrintJob("job" + rantime.ToString(), _printtimes));//取到后加入打印任务队列                    Console.WriteLine("job " + rantime.ToString() + " got!");                    if (JobHasGot != null)                        JobHasGot(this, new JobManagerEventArgs(_printtimes));//引发已取到打印任务事件                }            }                   }        /// <summary>        /// 打印任务管理参数类        /// </summary>        public class JobManagerEventArgs : EventArgs        {            private int _printtimes;//打印次数/打印机数量            public int Printtimes            {                get { return _printtimes; }                set { _printtimes = value; }            }            public JobManagerEventArgs(int printtimes)            {                this._printtimes = printtimes;            }        }        /// <summary>        /// 打印类        /// </summary>        public class Printer        {            public delegate void PrintFinishDel(string jobname);            public event PrintFinishDel PrintHasFinished;//打印完成事件            public void StartPrint(int printtimes)            {                for (int i = 0; i < printtimes; i++)                {                    Thread th = new Thread(new ParameterizedThreadStart(StartPrintProc));                    th.Start();                }            }            private void StartPrintProc(object obj)//打印线程            {                lock (jobqueue)                {                    if (jobqueue.Count != 0)                    {                        PrintJob job = jobqueue.Peek();//获取打印任务队列第一个打印任务                        if (job.Printcount != 0)                        {                            job.Printed();//当前打印机打印完成                            if (PrintHasFinished != null)                                PrintHasFinished(job.Jobname);//引发打印完成事件                        }                        else                            jobqueue.Dequeue();//全都打印完毕则移出队列                    }                }            }        }        /// <summary>        /// 打印任务类        /// </summary>        public class PrintJob        {            private int _printcount = 0;//当前任务还应打印几次            private string _jobname;            public int Printcount            {                get                {                    lock (this)                    {                        return _printcount;                    }                }                set { _printcount = value; }            }            public PrintJob(string jobname, int printcount)            {                this._jobname = jobname;                this._printcount = printcount;            }            public string Jobname            {                get { return _jobname; }                set { _jobname = value; }            }            public void Printed()            {                System.Threading.Interlocked.Decrement(ref _printcount);            }        }        static Queue<PrintJob> jobqueue = new Queue<PrintJob>();//打印任务队列        static Printer printer = new Printer();        static void Main(string[] args)        {            JobManager jm = new JobManager();            jm.StartGetJob(10);//10台打印机            jm.JobHasGot += new JobManager.JobHasGotDel(jm_JobHasGot);            printer.PrintHasFinished += new Printer.PrintFinishDel(printer_PrintHasFinished);            Console.ReadLine();        }        static void printer_PrintHasFinished(string jobname)        {            Console.WriteLine(jobname + " has finished!");//每个打印任务完成的通知        }        static void jm_JobHasGot(object sender,  JobManagerEventArgs e)        {            printer.StartPrint(e.Printtimes);//有新的打印任务了        }           } 


[解决办法]
线程不要先创建,等到有任务时再创建
主界面负责循环抓取所有打印任务,抓去后将任务根据不同打印机分类,添加到各自的任务列表,此时再开启打印子线程,子线程中循环读取自己的任务列表,直到所有的任务处理完再退出线程,处理过程中如果主界面再次从数据库中抓取到任务,此时添加到任务列表后判断子线程是否正在工作,如果没有工作再开启子线程

读书人网 >C#

热点推荐