123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Threading;
- using Terminal.Gui;
- namespace UICatalog.Scenarios {
- [ScenarioMetadata (Name: "Single BackgroundWorker", Description: "A single BackgroundWorker threading opening another Toplevel")]
- [ScenarioCategory ("Threading")]
- [ScenarioCategory ("Top Level Windows")]
- public class SingleBackgroundWorker : Scenario {
- public override void Run ()
- {
- Application.Top.Dispose ();
- Application.Run<MainApp> ();
- Application.Top.Dispose ();
- }
- public class MainApp : Toplevel {
- private BackgroundWorker worker;
- private List<string> log = new List<string> ();
- private DateTime? startStaging;
- private ListView listLog;
- public MainApp ()
- {
- var menu = new MenuBar (new MenuBarItem [] {
- new MenuBarItem ("_Options", new MenuItem [] {
- new MenuItem ("_Run Worker", "", () => RunWorker(), null, null, Key.CtrlMask | Key.R),
- null,
- new MenuItem ("_Quit", "", () => Application.RequestStop(), null, null, Key.CtrlMask | Key.Q)
- })
- });
- Add (menu);
- var statusBar = new StatusBar (new [] {
- new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Exit", () => Application.RequestStop()),
- new StatusItem(Key.CtrlMask | Key.P, "~^R~ Run Worker", () => RunWorker())
- });
- Add (statusBar);
- var top = new Toplevel ();
- top.Add (new Label ("Worker Log") {
- X = Pos.Center (),
- Y = 0
- });
- listLog = new ListView (log) {
- X = 0,
- Y = 2,
- Width = Dim.Fill (),
- Height = Dim.Fill ()
- };
- top.Add (listLog);
- Add (top);
- }
- private void RunWorker ()
- {
- worker = new BackgroundWorker () { WorkerSupportsCancellation = true };
- var cancel = new Button ("Cancel Worker");
- cancel.Clicked += (s,e) => {
- if (worker == null) {
- log.Add ($"Worker is not running at {DateTime.Now}!");
- listLog.SetNeedsDisplay ();
- return;
- }
- log.Add ($"Worker {startStaging}.{startStaging:fff} is canceling at {DateTime.Now}!");
- listLog.SetNeedsDisplay ();
- worker.CancelAsync ();
- };
- startStaging = DateTime.Now;
- log.Add ($"Worker is started at {startStaging}.{startStaging:fff}");
- listLog.SetNeedsDisplay ();
- var md = new Dialog ($"Running Worker started at {startStaging}.{startStaging:fff}", cancel);
- md.Add (new Label ("Wait for worker to finish...") {
- X = Pos.Center (),
- Y = Pos.Center ()
- });
- worker.DoWork += (s, e) => {
- var stageResult = new List<string> ();
- for (int i = 0; i < 500; i++) {
- stageResult.Add ($"Worker {i} started at {DateTime.Now}");
- e.Result = stageResult;
- Thread.Sleep (1);
- if (worker.CancellationPending) {
- e.Cancel = true;
- return;
- }
- }
- };
- worker.RunWorkerCompleted += (s, e) => {
- if (md.IsCurrentTop) {
- //Close the dialog
- Application.RequestStop ();
- }
- if (e.Error != null) {
- // Failed
- log.Add ($"Exception occurred {e.Error.Message} on Worker {startStaging}.{startStaging:fff} at {DateTime.Now}");
- listLog.SetNeedsDisplay ();
- } else if (e.Cancelled) {
- // Canceled
- log.Add ($"Worker {startStaging}.{startStaging:fff} was canceled at {DateTime.Now}!");
- listLog.SetNeedsDisplay ();
- } else {
- // Passed
- log.Add ($"Worker {startStaging}.{startStaging:fff} was completed at {DateTime.Now}.");
- listLog.SetNeedsDisplay ();
- Application.Refresh ();
- var builderUI = new StagingUIController (startStaging, e.Result as List<string>);
- builderUI.Load ();
- }
- worker = null;
- };
- worker.RunWorkerAsync ();
- Application.Run (md);
- }
- }
- public class StagingUIController : Window {
- Toplevel top;
- public StagingUIController (DateTime? start, List<string> list)
- {
- top = new Toplevel (Application.Top.Frame);
- top.KeyPress += (s,e) => {
- // Prevents Ctrl+Q from closing this.
- // Only Ctrl+C is allowed.
- if (e.KeyEvent.Key == (Key.Q | Key.CtrlMask)) {
- e.Handled = true;
- }
- };
- bool Close ()
- {
- var n = MessageBox.Query (50, 7, "Close Window.", "Are you sure you want to close this window?", "Yes", "No");
- return n == 0;
- }
- var menu = new MenuBar (new MenuBarItem [] {
- new MenuBarItem ("_Stage", new MenuItem [] {
- new MenuItem ("_Close", "", () => { if (Close()) { Application.RequestStop(); } }, null, null, Key.CtrlMask | Key.C)
- })
- });
- top.Add (menu);
- var statusBar = new StatusBar (new [] {
- new StatusItem(Key.CtrlMask | Key.C, "~^C~ Close", () => { if (Close()) { Application.RequestStop(); } }),
- });
- top.Add (statusBar);
- Title = $"Worker started at {start}.{start:fff}";
- ColorScheme = Colors.Base;
- Add (new ListView (list) {
- X = 0,
- Y = 0,
- Width = Dim.Fill (),
- Height = Dim.Fill ()
- });
- top.Add (this);
- }
- public void Load ()
- {
- Application.Run (top);
- }
- }
- }
- }
|