c#简单多线程实现

去年底工作上遇到一个奇葩的需求,之前写好的代码实时读取数据库,并做出一些操作;结果领导认为这样不好,要改成先去数据库把该做的都做了,结果存在数据库中,用的时候直接读数据库。试了一下,数据库数据量太多,顺序执行一遍需要4小时,不满足时间上的要求,于是只能改一改,改成多线程的了。

 

因为之前的程序是完整的,所以直接抠出来,加了个多线程的壳,凑合完成了领导要求。因为这种多线程不涉及线程间通讯,比较简单。下面给出源代码

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Configuration;
using System.IO;

namespace MultiTask
{
    class Program
    {
        static int m_timeout;

        static void Main(string[] args)
        {
            // 从配置文件中读入并发线程数和单个线程执行超时时间
            int concurrency = Convert.ToInt32(ConfigurationManager.AppSettings["concurrency"]);
            m_timeout = Convert.ToInt32(ConfigurationManager.AppSettings["timeout"]);

            // 创建线程任务排队,concurrency即为同时运行的线程数量 
            LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(concurrency);
            List<Task> tasks = new List<Task>();

            // Create a TaskFactory and pass it our custom scheduler. 
            TaskFactory factory = new TaskFactory(lcts);
            CancellationTokenSource cts = new CancellationTokenSource();

            var m_list = Init();   // 把数据从数据库中取出来,放在m_list中准备处理
            // 创建任务,并添加到任务工厂运行 
            foreach (var ele in m_list)
            {
                Info para = new Info(ele);  // 将数据塞到合适的数据结构中
                Task t1 = factory.StartNew(() => { TestRun(para); }, cts.Token);
                tasks.Add(t1);
            }

            // 等待任务完成
            Task.WaitAll(tasks.ToArray());
            cts.Dispose();

            Console.WriteLine("Successful completion.");

            KillProcess();
            //Console.ReadKey();
        }

        // 把数据从数据库中取出来
        static List<string> Init()
        {
            ...
            ...
        }

        // 万一有卡死的进程,杀掉
        static void KillProcess()
        {
            foreach (Process badprocess in Process.GetProcessesByName("TestRun"))
            {
                badprocess.Kill();
            }
        }

        static void TestRun(Info info)
        {
            Process p = new Process();
            p.StartInfo.FileName = "TestRun.exe";   // 运行以前的老程序
            p.StartInfo.Arguments = info.ID + " " + info.PRICE;
            p.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            p.Start();
            bool flag = p.WaitForExit(m_timeout); // 等待运行结束或超时
            if (!flag)  // 如果任务超时,打印log
            {
                FileStream fs = new FileStream("record.log", FileMode.Append);
                StreamWriter sw = new StreamWriter(fs);
                sw.WriteLine("[time out]: id = {0}, price = {1}", info.ID, info.PRICE);
                sw.Flush();
                sw.Close();
                fs.Close();
            }
        }
    }

    // 数据类
    public class Info
    {
        public int ID;
        public double PRICE;

        ...
        ...
    }
}

上面的程序运行后,会同时运行concurrency个线程。当其中一个线程运行完或超时结束后,就再运行一个新的线程,直到所有任务全部完成。就实现领导提的简单需求来说,已经足够了。

转载于:https://my.oschina.net/propagator/blog/1845885

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值