关于C#任务习题

1.每个任务最终会进入 RanToCompletion, Canceled, Faulted 三个状态其中之一,任务遇到了什么会情况会进入 Canceled 或 Faulted 状态.
答:(1)任务进入"Canceled"状态的情况通常包括:
1. 显式取消:任务的Cancel方法被调用,或者使用取消令牌进行取消。
2. 超时:任务在规定的时间内未能完成,超过了预定的等待时间。
3. 父任务取消:如果任务是作为另一个任务的子任务运行的,而父任务被取消了,子任务也会被取消。
4. 等待取消:任务在等待某个操作(如等待另一个任务完成或等待资源)时被取消。
(2)任务进入"Faulted"状态的情况通常包括:
1. 未处理异常:任务执行过程中抛出了未被处理的异常,导致任务进入故障状态。
2. 线程中止:任务所在的线程因为某种原因(如操作系统异常、内存溢出等)而中止,导致任务进入故障状态。
3. 内部错误:任务内部发生了错误,导致任务无法正常完成。
需要注意的是,任务的取消和故障状态不一定是由任务本身的代码问题引起的,还可能受到外部因素的影响,
如网络错误、资源不足等。因此,在编写任务时,应该考虑到可能出现的异常情况,并适当处理异常以避免任务进入故障状态.

任务进入Canceled状态是因为任务被取消了。这可以通过调用任务的Cancel方法来实现,或者通过传递一个取消标记给任务的执行方法来取消任务。
任务进入Faulted状态是因为任务执行过程中发生了异常。这可能是由于任务内部抛出了一个异常,或者由于任务的执行方法本身抛出了一个异常。

任务进入"Canceled"状态是在任务被取消时发生的。任务可以被取消,是由于调用了任务的Cancel方法或者是通过取消令牌进行取消。当任务被取消时,
它的状态会从"Running"(运行中)转变为"Canceled"(已取消)。在这种情况下,任务将立即停止执行并进入取消状态。

任务进入"Faulted"状态是在任务发生异常时发生的。当任务执行过程中抛出了异常并未被处理时,任务的状态将从"Running"(运行中)转变为"Faulted"(故障)。
在这种情况下,任务会停止执行并将异常信息传递给任务的调用者。任务的调用者可以通过检查任务的异常属性来获取异常信息。
常见的引发任务进入故障状态的情况包括:未处理异常、线程中止、内存溢出等。

2.简述如何处理 AggregateException 类型的异常
   答:AggregateException是一个异常集合,因为Task中可能抛出异常,所以我们需要新的类型来收集异常对象,处理异常时可采用AggregateException.Handle()方法,
为AggregateException中的每个异常都指定一个要执行的表达式,Handle()方法的重要特点在于它是一个断言,针对Handle()委托成功处理的任何异常,断言应返回True,
任何异常处理调用若为一个异常返回False,Handle()方法将返回新的AggregateException,其中包含了由这种异常构成的列表。
本文链接:https://blog.csdn.net/qq_38139402/article/details/110730505http://xn--https-bl8jz2ih7dl86lg05k//blog.csdn.net/qq_38139402/article/details/110730505

AggregateException是一个包装了一个或多个内部异常的异常。当使用多个任务并行执行,并且其中一个或多个任务发生了异常时,就会抛出AggregateException。
处理AagregateException的一种常见方法是使用其InnerExceptions属性来访问内部异常的集合。可以使用foreach循环遍历InnerExceptions属性,对每个内部异常进行处理。
另一种方法是使用AggregateException的Handle方法,该方法接受一个委托,可以对每个内部异常进行处理。
在处理AggregateException时,可以根据具体的需求选择适当的处理方式,例如记录日志、重试任务或向用户显示错误信息。
处理AggregateException类型的异常时,可以按照以下步骤进行:
1. 使用try-catch块捕获AggregateException。
2. 使用InnerExceptions属性获取AggregateException中包含的所有异常。
3. 遍历内部异常,并根据需要处理每个异常。
4. 可以选择重新抛出其中一个内部异常,或将所有内部异常汇总为一个更有意义的异常。
需要注意的是,要根据具体情况处理每个内部异常,并确保记录和处理异常的细节,以便更好地理解和调试代码中的问题。

1.构造一个例子既允许在任务执行前取消任务,又允许在任务执行中取消任务,取消任务后得体的继续操作

//5.构造一个例子既允许在任务执行前取消任务,又允许在任务执行中取消任务,取消任务后得体的继续操作

Console.WriteLine("是否取消任务?Y/N");
string chars = Console.ReadLine();
CancellationTokenSource cts = new CancellationTokenSource();
if (chars.ToUpper() == "Y")
{
    cts.Cancel();
}
else
{
    Task<bool> cancelTask = Task<bool>.Run(() => DoWork(cts.Token));
    Console.WriteLine("Press <Enter> to cancel the operation.");

    Console.ReadLine();

    cts.Cancel();
    Thread.Sleep(100);

    try
    {
        Console.WriteLine(cancelTask.Result);
    }
    catch (AggregateException ae)
    {
        ae.Handle((ex) =>
        {
            switch (ex)
            {
                case OperationCanceledException operationCanceledException:
                    Console.WriteLine("OperationCanceledException");
                    return true;
                default:
                    return false;
            }
        });
    }
}




bool DoWork(CancellationToken token)
{
    while (true)
    {
        Thread.Sleep(500);
        token.ThrowIfCancellationRequested();
        Console.WriteLine("运行中。。。");
    }
}

2.构造一个例子,根令牌取消时,分支令牌也被取消

//8.构造一个例子,根令牌取消时,分支令牌也被取消
Console.WriteLine("1 Step");
CancellationTokenSource cts1 = new CancellationTokenSource();
CancellationTokenSource cts2 = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token);
Console.WriteLine($"cts1.IsCancellationRequested: {cts1.Token.IsCancellationRequested}");
Console.WriteLine($"cts2.IsCancellationRequested: {cts2.Token.IsCancellationRequested}");
cts1.Cancel();
Console.WriteLine($"cts1.IsCancellationRequested: {cts1.Token.IsCancellationRequested}");
Console.WriteLine($"cts2.IsCancellationRequested: {cts2.Token.IsCancellationRequested}");

3.构造一个例子,让主线程等待多个任务中的任一一个完成

//11.构造一个例子,让主线程等待多个任务中的任一一个完成

Task task1 = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("第一个任务完成"); });
Task task2 = Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("第二个任务完成"); });
Task task3 = Task.Run(() => { Thread.Sleep(7000); Console.WriteLine("第三个任务完成"); });

Task oneCompletedTask = Task.WhenAny(task1, task2, task3);
oneCompletedTask.ContinueWith(t => Console.WriteLine("OneCompletedTask completed at " + DateTime.Now.ToString("HH:mm:ss")));

Console.ReadLine();

4.构造一个任务,当多个任务完成后该任务处于完成状态 

//12.构造一个任务,当多个任务完成后该任务处于完成状态 

Task task1 = Task.Run(() => { Thread.Sleep(2000); Console.WriteLine("第一个任务完成"); });
Task task2 = Task.Run(() => { Thread.Sleep(5000); Console.WriteLine("第二个任务完成"); });
Task task3 = Task.Run(() => { Thread.Sleep(7000); Console.WriteLine("第三个任务完成"); });

Task allCompletedTask = Task.WhenAll(task1, task2, task3);
allCompletedTask.ContinueWith(t => Console.WriteLine("AllCompletedTask completed at " + DateTime.Now.ToString("HH:mm:ss")));

Console.ReadLine();

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

创可贴治愈心灵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值