关于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();