检查c#中actionblock的completion异常,最直接的方式是通过await actionblock.completion并使用try-catch捕获aggregateexception;2. actionblock在并发处理中可能产生多个异常,这些异常会被封装成aggregateexception并在completion任务进入faulted状态时抛出;3. 除了await方式,还可通过检查completion任务的isfaulted、exception等属性非阻塞地获取异常信息;4. 使用continuewith可在completion完成时执行回调,实现异步错误处理与资源清理;5. 在actionblock的委托内部使用try-catch可捕获单个数据项处理异常,防止其影响整体completion状态;6. 内部捕获适用于需对单个失败项进行细粒度处理的场景,外部捕获适用于关注整体处理结果或要求任一错误即终止流程的场景;7. 两种策略可结合使用,内部处理可恢复错误,外部统一处理不可恢复错误,从而构建健壮的数据流处理管道。

检查C#中
ActionBlock
Completion
Task
ActionBlock
Task
await actionBlock.Completion
try-catch
AggregateException
ActionBlock
AggregateException
当你的
ActionBlock
Completion
Faulted
await
Completion
try-catch
using System;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
public class DataflowErrorHandling
{
public static async Task RunExample()
{
var actionBlock = new ActionBlock<int>(async data =>
{
Console.WriteLine($"Processing data: {data}");
if (data % 2 != 0) // Simulate an error for odd numbers
{
// 模拟一个异步操作中的错误
await Task.Delay(100);
throw new InvalidOperationException($"Error processing odd number: {data}");
}
await Task.Delay(50); // Simulate some work
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 });
for (int i = 0; i < 10; i++)
{
actionBlock.Post(i);
}
actionBlock.Complete(); // 告诉Block不再接收新的数据
try
{
// 等待所有数据处理完成,并捕获任何异常
await actionBlock.Completion;
Console.WriteLine("ActionBlock completed successfully.");
}
catch (AggregateException ae)
{
Console.WriteLine("ActionBlock completed with errors:");
foreach (var ex in ae.Flatten().InnerExceptions)
{
Console.WriteLine($" Caught exception: {ex.GetType().Name} - {ex.Message}");
}
}
catch (Exception ex)
{
// 捕获 AggregateException 之外的其它潜在异常,虽然对于 Completion 来说很少见
Console.WriteLine($"An unexpected error occurred: {ex.Message}");
}
Console.WriteLine("Example finished.");
}
public static void Main(string[] args)
{
RunExample().GetAwaiter().GetResult();
}
}这段代码展示了如何在一个
ActionBlock
await actionBlock.Completion
AggregateException
Dataflow
ae.Flatten().InnerExceptions
这个问题,我发现很多初学者,甚至一些有经验的开发者都会有点困惑。简单来说,
ActionBlock
TransformBlock
ActionBlock
当
ActionBlock
Complete()
AggregateException
Completion
Faulted
AggregateException
当然,并不是所有场景都适合直接
await
try-catch
Completion
ActionBlock
一种常见的方法是直接检查
Completion
IsFaulted
Exception
// 假设 actionBlock 已经完成了操作
if (actionBlock.Completion.IsFaulted)
{
Console.WriteLine("ActionBlock faulted without awaiting directly.");
// 直接访问 Exception 属性,它会返回 AggregateException
if (actionBlock.Completion.Exception is AggregateException ae)
{
foreach (var ex in ae.Flatten().InnerExceptions)
{
Console.WriteLine($" Non-awaiting check caught: {ex.GetType().Name} - {ex.Message}");
}
}
}
else if (actionBlock.Completion.IsCompletedSuccessfully)
{
Console.WriteLine("ActionBlock completed successfully (non-awaiting check).");
}这种方式在你不想阻塞当前线程,或者想在
ActionBlock
Task.ContinueWith()
actionBlock.Completion.ContinueWith(task =>
{
if (task.IsFaulted)
{
Console.WriteLine("Continuation: ActionBlock faulted.");
if (task.Exception is AggregateException ae)
{
foreach (var ex in ae.Flatten().InnerExceptions)
{
Console.WriteLine($" Continuation caught: {ex.GetType().Name} - {ex.Message}");
}
}
}
else if (task.IsCompletedSuccessfully)
{
Console.WriteLine("Continuation: ActionBlock completed successfully.");
}
else if (task.IsCanceled)
{
Console.WriteLine("Continuation: ActionBlock was canceled.");
}
}, TaskContinuationOptions.ExecuteSynchronously); // 或者 TaskContinuationOptions.LongRunning 等使用
ContinueWith
Completion
处理
ActionBlock
ActionBlock
Action<TInput>
Func<TInput, Task>
ActionBlock
Completion
Faulted
如果你想在
ActionBlock
try-catch
var actionBlockWithInternalCatch = new ActionBlock<int>(async data =>
{
try
{
Console.WriteLine($"Processing data with internal catch: {data}");
if (data % 2 != 0)
{
await Task.Delay(100);
throw new InvalidOperationException($"Simulated internal error for: {data}");
}
await Task.Delay(50);
Console.WriteLine($"Successfully processed: {data}");
}
catch (InvalidOperationException ex)
{
Console.WriteLine($" Internal catch: Failed to process {data}. Error: {ex.Message}");
// 这里你可以记录日志,或者对这个特定的数据项做一些补偿操作
// 注意:这里捕获的异常不会导致 Completion 任务 Faulted,
// 除非你选择重新抛出或在 catch 块中显式地让 Block Fault。
}
catch (Exception ex)
{
Console.WriteLine($" Internal catch: An unexpected error occurred for {data}. Error: {ex.Message}");
}
}, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 });
for (int i = 0; i < 10; i++)
{
actionBlockWithInternalCatch.Post(i);
}
actionBlockWithInternalCatch.Complete();
await actionBlockWithInternalCatch.Completion; // 这里的 Completion 可能不会 Faulted,取决于内部处理
Console.WriteLine("ActionBlock with internal catch finished.");在这个例子中,即使
InvalidOperationException
ActionBlock
Completion
Faulted
什么时候选择内部捕获,什么时候选择外部捕获
Completion
ActionBlock
try-catch
Completion
AggregateException
Completion
以上就是C#的ActionBlock的Completion异常怎么检查?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号