C# Task阻塞方式和延续操作

本文详细介绍了Task在C#中的多种启动方式,包括直接启动、使用Task工厂、同步执行及阻塞方式。同时,深入探讨了WaitAll、WaitAny、ContinueWith等高级用法,以及Task的延续操作和工厂中的延续操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Task启动的几种方式

		   var task = new Task(() =>
            {
                Console.WriteLine("工作线程" + Thread.CurrentThread.ManagedThreadId);
            });
            task.Start();
            //工厂
            Task.Factory.StartNew(() =>
            {
                Console.WriteLine("工作线程" + Thread.CurrentThread.ManagedThreadId);
            });

            Task.Run(() =>
            {
                Console.WriteLine("工作线程" + Thread.CurrentThread.ManagedThreadId);
            });


            //同步的方式
            task = new Task(() =>
            {
                Console.WriteLine("工作线程" + Thread.CurrentThread.ManagedThreadId);
            });
            //阻塞执行
            task.RunSynchronously();

Task阻塞方式和延续操作

下面开启2个线程

 Task task = new Task(() =>
            {
                Thread.Sleep(500);
                Console.WriteLine("工作线程1 " + DateTime.Now.ToString());
            });
            task.Start();
            Task task1 = new Task(() =>
            {
                Console.WriteLine("工作线程2 " + DateTime.Now.ToString());
            });
            task1.Start();

WaitAll


            //需要等待所有线程执行完毕,才会继续执行主线程
            Task.WaitAll(task, task1 );
            Console.WriteLine("主线程" + Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();

WaitAny

           //只要有一个Task执行完毕,就算完成,继续走主线程
            Task.WaitAny(task, task1);
            Console.WriteLine("主线程" + Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();

ContinueWith 不阻塞主线程,等两个线程执行完毕之后,执行延续任务


            //WhenAll 将task和task1执行完毕之后,在执行延续任务ContinueWith
            Task.WhenAll(task, task1).ContinueWith(t =>
            {
                Console.WriteLine("延续任务");
            });
            //WhenAll 执行完一个线程之后就开始执行延续任务
            Task.WhenAny(task, task1).ContinueWith(t =>
            {
                Console.WriteLine("延续任务");
            });
            Console.WriteLine("主线程" + Thread.CurrentThread.ManagedThreadId);
            Console.ReadLine();

Task工厂中的延续操作

           Task.Factory.ContinueWhenAll(new Task[2] { task, task1 }, (t) =>
            {
                Console.WriteLine("延续任务");
            });
           Task.Factory.ContinueWhenAny(new Task[2] { task, task1 }, (t) =>
            {
                Console.WriteLine("延续任务");
            });
### C#Task 的返回值处理 在 C# 中,`Task<T>` 表示一个异步操作的结果类型为 `TResult`。当创建启动这样的任务时,可以通过多种方式来获取其返回值。 #### 使用 Result 属性等待并获取返回值 可以使用 `Result` 属性阻塞当前线程直到任务完成,并取得它的结果: ```csharp var task = Task<int>.Run(() => { // 执行一些计算... return 42; }); // 阻塞主线程直至任务结束,并获得结果 int result = task.Result; Console.WriteLine($"The answer is {result}"); ``` 这种方法简单直接,但在 UI 或 ASP.NET 应用程序中不推荐因为这可能会引起死锁[^2]。 #### 异步等待任务完成 更现代的方式是利用 `async/await` 关键字来进行非阻塞性的操作: ```csharp public async Task ExampleAsync() { var task = Task.Run(async () => await Task.Delay(100).ContinueWith(t => 42)); // 不会阻塞主线程,在后台继续执行其他工作的同时等待任务完成 int result = await task; Console.WriteLine($"The answer is {result}"); } ``` 这种方式不仅提高了应用程序响应速度还简化了代码逻辑结构[^3]。 #### 处理带有回调函数的任务 还可以通过注册延续(continuation),即指定另一个将在前一任务完成后立即运行的新任务作为替代方案之一: ```csharp Task<int> task = Task.Factory.StartNew(() => { Thread.Sleep(500); return 8 * 6; }).ContinueWith((prevTask) => prevTask.Result + 7); task.Wait(); Console.WriteLine($"Final computed value: {task.Result}"); ``` 此模式允许开发者定义一系列相互依赖的工作项链表形式排列起来依次被执行[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值