.NET Framework4.0异步编程的取消

4.0里面没有async,await这些关键字,在使用异步编程时没有4.5以上版本方便,但是对于异步操作,微软还是封装了Task类,该类可以很方便的取消异步操作。废话不多说,上例子。

        
//该类的主要作用是告知Task<T>类,其任务被取消
        private static CancellationTokenSource cts = new CancellationTokenSource();
        static void Main(string[] args)
        {
            string fileName = "D:\\图片11";
            Console.WriteLine("输入q退出任务。");
            Console.WriteLine("文件位置:" + fileName);
       
            //计算文件夹大小的方法,可以理解为另一个线程
            Task<Int64> t = GettingFileSizeAsync(fileName);
            //开始执行
            t.Start();
            Console.WriteLine("正在计算...");
            string s = Console.ReadLine();
            //输入q,取消任务,此时cts会强制让当前Task抛出一个OperationCanceledException异常
            if (s == "q")
            {
                cts.Cancel();
            }
            Console.ReadKey();
        }
    
        /// <summary>
        /// 封装一个异步方法,令其异步化,以便进行取消操作
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private static Task<Int64> GettingFileSizeAsync(string fileName)
        {
            Task<Int64> t = new Task<Int64>(() => {
                try
                {
                    return GetFileSize(fileName);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                    return 0;
                }
            }, cts.Token);
            return t;
        }

        /// <summary>
        /// 递归返回文件夹大小,该方法效率比较低,实际应用中不建议使用
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private static Int64 GetFileSize(string fileName)
        {
            //为了方便,循环10次,每次睡眠1秒
            for (int i = 0; i < 10; i++)
            {
                Thread.Sleep(1000);
                //每次执行该操作,都会检查是否已取消,若已取消,
                //则该方法会抛出OperationCanceledException异常
                cts.Token.ThrowIfCancellationRequested();
            } 
            Int64 totalSize = 0;
            if (!Directory.Exists(fileName))
            {
                throw new DirectoryNotFoundException("找不到文件:" + fileName);
            }
            DirectoryInfo dInfo = new DirectoryInfo(fileName);
            DirectoryInfo[] childInfo = dInfo.GetDirectories();
            FileInfo[] files = dInfo.GetFiles();
            foreach (FileInfo f in files)
            {
                totalSize += f.Length;
            }
            foreach (DirectoryInfo info in childInfo)
            {
                totalSize += GetFileSize(info.FullName);
            }
            return totalSize;
        }

 

posted @ 2015-03-25 23:08  尋找一個證明  阅读(842)  评论(0)    收藏  举报