Skip to content

Consider implenting System.Progress design pattern (German only discussion) #2

@jochenwezel

Description

@jochenwezel

Question: In CompuMaster.TaskManagement könnte man evtl. - falls dort überhaupt sinnvoll - diese Funktionalität nachrüsten. Die Frage ist: macht es überhaupt dort Sinn?

Ja, das kann in CompuMaster.TaskManagement sinnvoll sein – aber nicht zwingend. Es hängt davon ab, welches Progress-Szenario Sie dort abdecken möchten.

Aus Ihrem README ist klar: Die Library modelliert bereits TaskBundles → TaskItems → TaskSteps, inkl. Rollback/Fail-Strategien, geschätzter Dauer, Abbruch und optionaler WinForms-UI. ([GitHub]1)
Damit haben Sie schon eine “Progress-Struktur” (Step-Start/Step-Ende, Status, Timing). System.Progress<T> wäre also kein Muss, sondern eher ein Adapter/Komfort-Feature.

Wann Progress<T> dort wirklich Sinn macht

1) „Sub-Progress innerhalb eines einzelnen Steps“

Aktuell ist ein Step „atomar“ gedacht (“A task step is an atomic step…”). ([GitHub]1)
Wenn Sie aber Steps haben wie „Datei kopieren“, „DB-Migration“, „Download“, dann will man innerhalb eines Steps z. B. 0–100% melden (und nicht nur „Step läuft / Step fertig“).

Hier ist IProgress<T> Gold wert, weil der Step-Implementierer progress melden kann, ohne die UI zu kennen.

2) UI-/Host-agnostische Progress-Ausgabe

Sie haben WinForms-UI im Repo, aber die Core-Library ist auch ohne UI nutzbar. IProgress<T> ist eine saubere, standardisierte Schnittstelle, damit:

  • WinForms/WPF automatisch thread-sicher updaten,
  • Console/Service/Logger ebenfalls Fortschritt bekommen,
  • ohne dass Sie eine eigene Event-Flut oder UI-Abhängigkeiten im Core erzwingen.

3) Async-first Schritte

Falls Sie mittelfristig Steps als Func<CancellationToken, Task> (oder ähnlich) unterstützen wollen: IProgress<T> passt perfekt zu async/await.

Wann es eher nicht lohnt

Wenn Ihr UI/Engine ohnehin schon:

  • bei jedem Step-Start/Step-Ende Events feuert,
  • die Fortschrittsanzeige primär „Stepweise“ ist (nicht innerhalb eines Steps),
  • und Sie keine externen „Long-running“ Operationen mit echtem Prozentwert haben,

…dann ist Progress<T> hauptsächlich „nice to have“, aber wenig Mehrwert.

Vorschlag: Minimal-invasive Erweiterung (backwards compatible)

Ziel: Kein Breaking Change, aber IProgress<> optional.

  1. Definieren Sie ein neutrales Progress-DTO, z. B.:
  • TaskProgressInfo

    • BundleName/Id, ItemName/Id, StepName/Id
    • Phase (Starting/Running/Completed/Failed/Rollback…)
    • optional: Percent (nullable), Message, Exception (optional)
  1. Erweitern Sie den Executor um einen optionalen Parameter:
  • ExecuteAsync(..., IProgress<TaskProgressInfo>? progress = null, CancellationToken ct = default)
  1. Standard-Progress aus Ihrer Engine:
  • Bei Step-Start: progress?.Report(... Starting ...)
  • Bei Step-Ende: ... Completed/Failed ...
  1. Sub-Progress ermöglichen:
  • Entweder: Step-Delegate bekommt IProgress<TaskProgressInfo> injiziert
  • oder: Steps implementieren ein Interface wie IProgressReportingStep, das die Engine beim Ausführen mit progress versorgt.

Damit können Ihre bestehenden WinForms-Controls einfach einen Progress<TaskProgressInfo> anlegen und UI updaten – ohne Cross-Thread-Basteln.


Wenn Sie mir sagen, ob Sie eher „Stepweise Progress“ oder „Sub-Progress innerhalb Steps“ brauchen, kann ich Ihnen eine konkrete API-Skizze machen (inkl. Namensvorschlägen, Datenmodell und wie das sauber mit Rollback-Phasen zusammenspielt).

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions