开源代码分享: GoldArch.TaskWrapperReport task执行生命周期封装,处理过程报告
.NET Windows 窗体库用于简化后台任务管理,并带有用于进度报告和状态显示的集成 UI 控件。
该GoldArch.TaskWrapper库(位于GoldArch.TaskWrapperReport代码中的命名空间结构中)提供了一个强大的TaskWrapper类来执行异步操作,同时提供对进度报告、取消、状态管理和错误处理的细粒度控制。它由一套自定义 UI 控件补充,旨在有效地可视化任务进度和日志。
所提供的解决方案包括:
- GoldArch.TaskWrapper(类库组件):包含核心
TaskWrapper逻辑和可重用的 UI 控件。它们组织在GoldArch.TaskWrapperReport.TaskWrapperCore、GoldArch.TaskWrapperReport.TaskReportControl和 等命名空间中GoldArch.TaskWrapperReport.Common。 - GoldArch.TaskWrapper.Simple(WinForms 应用程序):一个展示该库的各种功能和 UI 控件的演示项目。
- 异步任务执行:在后台线程上运行长时间运行的操作,而不会冻结 UI。
- 进度报告:任务可以使用对象报告进度更新,包括消息、百分比值和严重性级别(
Information、、、等)Warning。ErrorSuccessTaskProgressInfo - CancellationToken 支持:通过 优雅地取消任务
CancellationTokenSource。 - 状态管理:任务通过枚举中定义的明确状态(,,,,,,)
Idle进行转换。StartingRunningCancellingCompletedFaultedCancelledTaskExecutionState - 错误处理:捕获并报告任务中的异常,并提供
TaskStateChangedEventArgs包含异常详细信息的事件。 - 生命周期操作:定义在任务开始之前(
BeforeDoWorkAction)和任务完成之后(AfterCompletionAction)要执行的操作。 - 可配置堆栈跟踪显示:在报告中显示或隐藏错误堆栈跟踪的选项(
ShowErrorStackTrace属性)。
TextProgressBar:ProgressBar可直接在其上显示文本的自定义,具有可配置的文本/进度颜色和CustomText属性。RichTextBoxEx:增强了RichTextBox自动滚动行为,尤其是在用户可能已滚动到其他位置时追加文本。它使用 Win32 消息(例如EM_GETSCROLLPOS和 )EM_SETSCROLLPOS进行滚动管理。StatusProgressBar:一个紧凑的用户控件,使用TextProgressBar将所有任务状态(空闲、运行、已完成、错误等)和进度信息以格式化文本的形式显示在进度条上。提供针对不同状态(例如TextFormatIdle、ProgressBarRunningColor)的丰富颜色和文本自定义功能。StatusProgressDisplay:一个用户控件,具有Label状态文本(lblStatus)和TextProgressBar进度条可视化效果。它清晰地区分了状态信息和进度条可视化效果,并可自定义不同状态的颜色和文本(例如StatusTextIdle、ProgressBarIdleColor)。TaskReportRichTextBox:一个全面的用户控件,集成了TextProgressBar用于RichTextBoxEx详细日志记录的 和取消按钮。它内部管理TaskWrapperInstance,并提供丰富的任务报告界面,并可根据不同的日志级别(例如InfoTextColor、ErrorTextColor)自定义文本颜色。
TaskExecutionHelper:提供静态辅助方法(ExecuteAction, ),以便使用更简洁的语法ExecuteAsyncFunc快速运行任务。TaskWrapperControlInvokeHelper:Control.Invoke使用和从非 UI 线程安全地调用 UI 控件上的操作的实用程序Control.BeginInvoke。TaskReportUtil:简单的实用程序,例如,用于格式化时间戳(例如Now年月日时分秒)。
TaskProgressInfo:封装进度更新细节(内容消息、进度文本、进度值、报告级别)。ReportLevel(枚举):定义进度消息的性质(例如,,,,,)Information。WarningErrorSuccessDetailTaskExecutionState(枚举):表示任务的当前状态(例如Idle,,,,)Running。CompletedFaulted
GoldArch.TaskWrapper/(概念库根)Common/ControlInvokeHelper.csProperties/(AssemblyInfo.cs、Resources.Designer.cs、Settings.Designer.cs)TaskReportControl/(TextProgressBar.cs、RichTextBoxEx.cs、StatusProgressBar.cs、StatusProgressDisplay.cs、TaskReportRichTextBox.cs 及其 .designer.cs 文件)TaskWrapperCore/(TaskWrapper.cs、TaskProgressInfo.cs、TaskReportUtil.cs、TaskExecutionHelper.cs)
GoldArch.TaskWrapper.Simple/(演示应用程序)Properties/(AssemblyInfo.cs、Resources.Designer.cs、Settings.Designer.cs)Program.csMainForm.csSimpleProgressForm.csSimpleProgressForm02.csSimpleProgressForm03.csApp.config
此控件是独立的并管理其自己的TaskWrapperInstance。
// In your Form:
// Add TaskReportRichTextBox control (e.g., taskReportControl1) via designer or code.
// Configure in MainForm.cs or similar:
private void SetupTaskReportControl()
{
taskReportControl1.ShowCancelButton = true;
taskReportControl1.ShowErrorStackTraceInWrapper = true;
taskReportControl1.IsScrollToEndAfterReport = true;
taskReportControl1.TaskWrapperInstance.StateChanged += (s, e) => {
// Custom logic based on task state
};
}
private void BtnStartComplexTask_Click(object sender, EventArgs e)
{
var wrapper = taskReportControl1.TaskWrapperInstance;
// Check if task is already running
if (wrapper.CurrentState == TaskExecutionState.Running || wrapper.CurrentState == TaskExecutionState.Starting)
{
MessageBox.Show("A task is already running.");
return;
}
taskReportControl1.ResetReportControl();
wrapper.DoWorkFuncAsync = async (token, progress) =>
{
for (int i = 0; i <= 10; i++)
{
token.ThrowIfCancellationRequested();
await Task.Delay(500, token).ConfigureAwait(false);
progress.Report(new TaskProgressInfo(
content: $"Step {i + 1} logged. Details...\n",
progressText: $"Processing item {i + 1} of 11",
progressValue: (i + 1) * (100 / 11), // Example calculation
level: i > 7 ? ReportLevel.Warning : ReportLevel.Information
));
}
progress.Report(new TaskProgressInfo("All steps processed successfully!", ReportLevel.Success));
return null; // Success
};
wrapper.StartTaskAsync();
}
// To report messages not directly tied to the TaskWrapper's current task:
private void BtnReportDirectly_Click(object sender, EventArgs e
