ProgressHelper.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. using PTMedicalInsurance.Variables;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9. using System.Windows.Forms;
  10. namespace PTMedicalInsurance.Common
  11. {
  12. //public class ProgressDialog : Form
  13. //{
  14. // private ProgressBar progressBar1;
  15. // private Label labelStatus;
  16. // private Button cancelButton;
  17. // BackgroundWorker _backgroundWorker;
  18. // private int maximum;
  19. // private ProgressBarStyle _pbStyle = ProgressBarStyle.Marquee;
  20. // private string _header = "正在查询...";
  21. // private int _marqueeAnimationSpeed = 50;
  22. // public string HeaderText
  23. // {
  24. // get { return _header; }
  25. // set { this.Text =_header = value; }
  26. // }
  27. // public ProgressBarStyle PBStyle
  28. // {
  29. // get { return _pbStyle; }
  30. // set { progressBar1.Style =_pbStyle = value; }
  31. // }
  32. // public int MQSpeed
  33. // {
  34. // get { return _marqueeAnimationSpeed; }
  35. // set { progressBar1.MarqueeAnimationSpeed =_marqueeAnimationSpeed = value; }
  36. // }
  37. // public ProgressDialog()
  38. // {
  39. // Init();
  40. // }
  41. // public ProgressDialog(BackgroundWorker backgroundWorker)
  42. // {
  43. // Init();
  44. // _backgroundWorker = backgroundWorker;
  45. // }
  46. // private void Init()
  47. // {
  48. // Application.EnableVisualStyles();
  49. // this.Text = _header;
  50. // this.StartPosition = FormStartPosition.CenterParent;
  51. // this.FormBorderStyle = FormBorderStyle.FixedDialog;
  52. // this.MaximizeBox = false;
  53. // this.MinimizeBox = false;
  54. // this.ShowInTaskbar = false;
  55. // this.TopMost = true; // 确保进度条始终在最前面
  56. // this.CenterToScreen();
  57. // progressBar1 = new ProgressBar
  58. // {
  59. // Location = new System.Drawing.Point(12, 12),
  60. // Size = new System.Drawing.Size(260, 23)
  61. // };
  62. // //progressBar1.Style = ProgressBarStyle.Continuous;
  63. // progressBar1.Style = _pbStyle;
  64. // progressBar1.MarqueeAnimationSpeed = _marqueeAnimationSpeed;
  65. // Controls.Add(progressBar1);
  66. // labelStatus = new Label
  67. // {
  68. // Location = new System.Drawing.Point(12, 41),
  69. // Size = new System.Drawing.Size(260, 23)
  70. // };
  71. // Controls.Add(labelStatus);
  72. // //// 初始化取消按钮
  73. // //cancelButton = new Button
  74. // //{
  75. // // Text = "取消",
  76. // // Location = new System.Drawing.Point(197, 41), // 设置适当的位置
  77. // // Size = new System.Drawing.Size(75, 23) // 设置按钮大小
  78. // //};
  79. // //cancelButton.Click += CancelButton_Click; // 添加点击事件处理程序
  80. // //Controls.Add(cancelButton);
  81. // // 初始化取消按钮
  82. // cancelButton = new Button
  83. // {
  84. // Text = "取消",
  85. // Location = new System.Drawing.Point(197, 60), // 修改Y坐标以避免与labelStatus重叠
  86. // Size = new System.Drawing.Size(75, 23) // 设置按钮大小
  87. // };
  88. // cancelButton.Click += CancelButton_Click; // 添加点击事件处理程序
  89. // Controls.Add(cancelButton);
  90. // // 设置默认样式
  91. // SetStyle(ControlStyles.ResizeRedraw, true);
  92. // ClientSize = new System.Drawing.Size(284, 100);
  93. // }
  94. // // 允许外部设置进度条的值
  95. // public int ProgressValue
  96. // {
  97. // set { if (InvokeRequired) Invoke(new Action(() => progressBar1.Value = value)); else progressBar1.Value = value; }
  98. // }
  99. // public void UpdateProgress(int progress)
  100. // {
  101. // //if (progressBar1.InvokeRequired)
  102. // //{
  103. // // progressBar1.Invoke(new Action<int>(UpdateProgress), progress);
  104. // //}
  105. // //else
  106. // //{
  107. // // progressBar1.Value = progress;
  108. // // //这个有点糊涂了,这个进度条显示总是少一个
  109. // // labelStatus.Text = $"已完成 {progress}/{maximum}";
  110. // //}
  111. // if (this.IsHandleCreated)
  112. // {
  113. // this.Invoke((MethodInvoker)delegate
  114. // {
  115. // progressBar1.Value = progress;
  116. // //这个有点糊涂了,这个进度条显示总是少一个
  117. // labelStatus.Text = $"已完成 {progress}/{maximum}";
  118. // ///在Windows Forms应用程序中,控件的更新通常是由操作系统消息循环处理的。当你修改一个控件的属性(如 Text 或 Value),
  119. // ///这些更改并不会立即反映在界面上,而是会被放入队列等待下一个合适的时机进行绘制。这是因为直接更新控件属性并不会强制执行重绘操作,
  120. // ///系统可能会批量处理多个更新以提高效率。
  121. // ///使用 Refresh() 方法 调用控件的 Refresh() 方法会强制该控件立即重绘自身。这包括清除控件并重新绘制其所有内容
  122. // if (progress == maximum)
  123. // {
  124. // progressBar1.Refresh();
  125. // labelStatus.Refresh();
  126. // }
  127. // });
  128. // }
  129. // }
  130. // public void SetProgress(int max)
  131. // {
  132. // maximum = max;
  133. // progressBar1.Maximum = maximum;
  134. // }
  135. // // 允许外部设置状态文本
  136. // public string StatusText
  137. // {
  138. // set { if (InvokeRequired) Invoke(new Action(() => labelStatus.Text = value)); else labelStatus.Text = value; }
  139. // }
  140. // //异步展示
  141. // public async void ShowAsync()
  142. // {
  143. // await Task.Run(() => progressBar1.Show());
  144. // }
  145. // private void CancelButton_Click(object sender, EventArgs e)
  146. // {
  147. // // 这里可以放置取消操作的逻辑
  148. // // 比如通知BackgroundWorker取消工作
  149. // if (_backgroundWorker != null && _backgroundWorker.WorkerSupportsCancellation)
  150. // {
  151. // _backgroundWorker.CancelAsync();
  152. // }
  153. // this.Close(); // 关闭对话框
  154. // }
  155. //}
  156. //public class DataLoader : IDisposable
  157. //{
  158. // private BackgroundWorker _backgroundWorker = new BackgroundWorker();
  159. // /// <summary>
  160. // /// 接收一个动态可变的入参,各种参数均可接收;回调函数返回总条数和当前进度
  161. // /// </summary>
  162. // /// <typeparam name="T1"></typeparam>
  163. // /// <param name="o"></param>
  164. // /// <param name="err"></param>
  165. // /// <param name="progressCallback"></param>
  166. // /// <param name="progressMaxCallback"></param>
  167. // /// <returns></returns>
  168. // public delegate int MyFunc<T1>(object[] o,out T1 err,ProgressCallback progressCallback,ProgressMaxCallback progressMaxCallback);
  169. // private MyFunc<string> _delegateFunc;
  170. // private ProgressDialog progressDialog ;
  171. // private Form mainForm;
  172. // private object[] _o;
  173. // // 定义进度回调委托
  174. // //返回当前进度
  175. // public delegate void ProgressCallback(int progress);
  176. // //返回进度条总条数
  177. // public delegate void ProgressMaxCallback(int max);
  178. // public DataLoader(MyFunc<string> delegateFunc, Form frm)
  179. // {
  180. // mainForm = frm;
  181. // _delegateFunc = delegateFunc ?? throw new ArgumentNullException(nameof(delegateFunc));
  182. // }
  183. // public DataLoader(Form frm)
  184. // {
  185. // mainForm = frm;
  186. // // 配置 BackgroundWorker
  187. // _backgroundWorker.WorkerReportsProgress = true;
  188. // _backgroundWorker.WorkerSupportsCancellation = true;
  189. // _backgroundWorker.DoWork += BackgroundWorker_DoWork;
  190. // _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
  191. // _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
  192. // progressDialog = new ProgressDialog(_backgroundWorker);
  193. // }
  194. // public void SetDelagate(MyFunc<string> delegateFunc)
  195. // {
  196. // _delegateFunc = delegateFunc ?? throw new ArgumentNullException(nameof(delegateFunc));
  197. // }
  198. // public void SetProgressBar(ProgressBarStyle pbStyle,string headerText,int mqSpeed)
  199. // {
  200. // progressDialog.PBStyle = pbStyle;
  201. // progressDialog.HeaderText = headerText;
  202. // progressDialog.MQSpeed = mqSpeed;
  203. // }
  204. // public void Start(int total, Action<int, string> onCompleted)
  205. // {
  206. // // 配置 BackgroundWorker
  207. // _backgroundWorker.WorkerReportsProgress = true;
  208. // _backgroundWorker.WorkerSupportsCancellation = true;
  209. // _backgroundWorker.DoWork += BackgroundWorker_DoWork;
  210. // _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
  211. // _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
  212. // progressDialog = new ProgressDialog(_backgroundWorker);
  213. // if (mainForm == null)
  214. // {
  215. // progressDialog.Show();
  216. // }
  217. // else
  218. // {
  219. // progressDialog.Show(mainForm);
  220. // }
  221. // if (_backgroundWorker.IsBusy) return;
  222. // this._onCompleted = onCompleted;
  223. // _backgroundWorker.RunWorkerAsync(total);
  224. // }
  225. // public void Start(Action<int, string> onCompleted)
  226. // {
  227. // // 配置 BackgroundWorker
  228. // _backgroundWorker.WorkerReportsProgress = true;
  229. // _backgroundWorker.WorkerSupportsCancellation = true;
  230. // _backgroundWorker.DoWork += BackgroundWorker_DoWork;
  231. // _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
  232. // _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
  233. // progressDialog = new ProgressDialog(_backgroundWorker);
  234. // if (mainForm == null)
  235. // {
  236. // progressDialog.Show();
  237. // }
  238. // else
  239. // {
  240. // progressDialog.Show(mainForm);
  241. // }
  242. // if (_backgroundWorker.IsBusy) return;
  243. // this._onCompleted = onCompleted;
  244. // _backgroundWorker.RunWorkerAsync();
  245. // }
  246. // public void Start(object[] o,Action<int, string> onCompleted)
  247. // {
  248. // // 配置 BackgroundWorker
  249. // _backgroundWorker.WorkerReportsProgress = true;
  250. // _backgroundWorker.WorkerSupportsCancellation = true;
  251. // _backgroundWorker.DoWork += BackgroundWorker_DoWorkO;
  252. // _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
  253. // _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
  254. // progressDialog = new ProgressDialog(_backgroundWorker);
  255. // if (mainForm == null)
  256. // {
  257. // progressDialog.Show();
  258. // }
  259. // else
  260. // {
  261. // progressDialog.Show(mainForm);
  262. // }
  263. // if (_backgroundWorker.IsBusy) return;
  264. // this._onCompleted = onCompleted;
  265. // _backgroundWorker.RunWorkerAsync();
  266. // }
  267. // private Action<int, string> _onCompleted;
  268. // private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
  269. // {
  270. // // 调用传入的方法
  271. // string errMsg = "";
  272. // int result = -1;
  273. // //注意,如果_queryExportDataAction 事件里需要更新UI 必须使用 Control.Invoke 或 Control.BeginInvoke。否则会导致程序卡死
  274. // ///类似这样:this.Invoke((MethodInvoker)delegate {labelProgress.Text = $"Progress: {progress}%"; });
  275. // result = _delegateFunc(null, out errMsg, (progress) =>
  276. // {
  277. // if (!_backgroundWorker.CancellationPending)
  278. // {
  279. // _backgroundWorker.ReportProgress(progress);
  280. // }
  281. // else
  282. // {
  283. // // 如果用户请求了取消,则跳出循环或采取其他措施
  284. // // 这个异常处理查询下
  285. // throw new OperationCanceledException();
  286. // }
  287. // },
  288. // (max) =>
  289. // {
  290. // if (!_backgroundWorker.CancellationPending)
  291. // {
  292. // progressDialog.SetProgress(max); ;
  293. // }
  294. // else
  295. // {
  296. // // 如果用户请求了取消,则跳出循环或采取其他措施
  297. // // 这个异常处理查询下
  298. // throw new OperationCanceledException();
  299. // }
  300. // }
  301. // );
  302. // e.Result = Tuple.Create(result, errMsg);
  303. // }
  304. // private void BackgroundWorker_DoWorkO(object sender, DoWorkEventArgs e)
  305. // {
  306. // // 调用传入的方法
  307. // string errMsg = "";
  308. // int result = -1;
  309. // //注意,如果_queryExportDataAction 事件里需要更新UI 必须使用 Control.Invoke 或 Control.BeginInvoke。否则会导致程序卡死
  310. // ///类似这样:this.Invoke((MethodInvoker)delegate {labelProgress.Text = $"Progress: {progress}%"; });
  311. // result = _delegateFunc(_o, out errMsg, (progress) =>
  312. // {
  313. // if (!_backgroundWorker.CancellationPending)
  314. // {
  315. // _backgroundWorker.ReportProgress(progress);
  316. // }
  317. // else
  318. // {
  319. // // 如果用户请求了取消,则跳出循环或采取其他措施
  320. // // 这个异常处理查询下
  321. // throw new OperationCanceledException();
  322. // }
  323. // },
  324. // (max) =>
  325. // {
  326. // if (!_backgroundWorker.CancellationPending)
  327. // {
  328. // progressDialog.SetProgress(max); ;
  329. // }
  330. // else
  331. // {
  332. // // 如果用户请求了取消,则跳出循环或采取其他措施
  333. // // 这个异常处理查询下
  334. // throw new OperationCanceledException();
  335. // }
  336. // }
  337. // );
  338. // e.Result = Tuple.Create(result, errMsg);
  339. // }
  340. // private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  341. // {
  342. // if (!_backgroundWorker.CancellationPending)
  343. // {
  344. // System.Threading.Thread.Sleep(1000);
  345. // }
  346. // progressDialog.Close();
  347. // if (e.Error != null)
  348. // {
  349. // // 处理错误
  350. // MessageBox.Show($"An error occurred: {e.Error.Message}");
  351. // }
  352. // else if (e.Cancelled)
  353. // {
  354. // // 处理取消的情况
  355. // MessageBox.Show("Operation was cancelled.");
  356. // }
  357. // else
  358. // {
  359. // var resultTuple = (Tuple<int, string>)e.Result;
  360. // int result = resultTuple.Item1;
  361. // string errMsg = resultTuple.Item2;
  362. // // 调用回调函数,传递结果和错误信息
  363. // _onCompleted?.Invoke(result, errMsg);
  364. // }
  365. // Dispose();
  366. // }
  367. // private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  368. // {
  369. // progressDialog.UpdateProgress(e.ProgressPercentage );
  370. // }
  371. // public void Dispose()
  372. // {
  373. // _backgroundWorker.Dispose();
  374. // progressDialog.Dispose();
  375. // }
  376. //}
  377. [DesignerCategory("Code")]
  378. public class ProgressDialog : Form
  379. {
  380. private ProgressBar _progressBar;
  381. private Label _labelStatus;
  382. private Button _cancelButton;
  383. private BackgroundWorker _backgroundWorker;
  384. private int _maximum = 100;
  385. private string _header = "正在查询...";
  386. public string HeaderText
  387. {
  388. get => _header;
  389. set { Text = _header = value; }
  390. }
  391. public ProgressBarStyle PBStyle
  392. {
  393. get => _progressBar.Style;
  394. set => _progressBar.Style = value;
  395. }
  396. public int MQSpeed
  397. {
  398. get => _progressBar.MarqueeAnimationSpeed;
  399. set => _progressBar.MarqueeAnimationSpeed = value;
  400. }
  401. public ProgressDialog()
  402. {
  403. InitComponent();
  404. }
  405. public ProgressDialog(BackgroundWorker backgroundWorker) : this()
  406. {
  407. _backgroundWorker = backgroundWorker;
  408. }
  409. public void InitComponent()
  410. {
  411. Application.EnableVisualStyles();
  412. // 设置窗体样式
  413. Text = _header;
  414. StartPosition = FormStartPosition.CenterParent;
  415. FormBorderStyle = FormBorderStyle.FixedDialog;
  416. MaximizeBox = false;
  417. MinimizeBox = false;
  418. ShowInTaskbar = false;
  419. TopMost = true;
  420. ClientSize = new Size(284, 100);
  421. CenterToScreen();
  422. // 初始化进度条
  423. _progressBar = new ProgressBar
  424. {
  425. Location = new Point(12, 12),
  426. Size = new Size(260, 23),
  427. Style = ProgressBarStyle.Marquee,
  428. MarqueeAnimationSpeed = 50
  429. };
  430. Controls.Add(_progressBar);
  431. // 状态标签
  432. _labelStatus = new Label
  433. {
  434. Location = new Point(12, 41),
  435. Size = new Size(260, 23)
  436. };
  437. Controls.Add(_labelStatus);
  438. // 取消按钮
  439. _cancelButton = new Button
  440. {
  441. Text = "取消",
  442. Location = new Point(197, 60),
  443. Size = new Size(75, 23)
  444. };
  445. _cancelButton.Click += CancelButton_Click;
  446. Controls.Add(_cancelButton);
  447. SetStyle(ControlStyles.ResizeRedraw, true);
  448. }
  449. public int ProgressValue
  450. {
  451. set
  452. {
  453. if (this.IsHandleCreated)
  454. {
  455. this.InvokeIfRequired(() =>
  456. {
  457. _progressBar.Value = value;
  458. _labelStatus.Text = $"已完成 {value}/{_maximum}";
  459. if (value == _maximum || value >= _progressBar.Maximum)
  460. {
  461. _progressBar.Refresh();
  462. _labelStatus.Refresh();
  463. }
  464. });
  465. }
  466. }
  467. }
  468. public void SetProgress(int max)
  469. {
  470. _maximum = max;
  471. _progressBar.Maximum = max;
  472. }
  473. public string StatusText
  474. {
  475. set => this.InvokeIfRequired(() => _labelStatus.Text = value);
  476. }
  477. private void CancelButton_Click(object sender, EventArgs e)
  478. {
  479. if (_backgroundWorker != null && _backgroundWorker.WorkerSupportsCancellation)
  480. {
  481. _backgroundWorker.CancelAsync();
  482. }
  483. this.Close();
  484. }
  485. public async void ShowAsync()
  486. {
  487. await Task.Run(() =>
  488. {
  489. Application.Run(this);
  490. });
  491. }
  492. protected override void OnClosed(EventArgs e)
  493. {
  494. base.OnClosed(e);
  495. _backgroundWorker = null;
  496. }
  497. }
  498. // 扩展方法:简化 Invoke 操作
  499. public static class ControlExtensions
  500. {
  501. public static void InvokeIfRequired(this Control control, MethodInvoker action)
  502. {
  503. if (control.InvokeRequired)
  504. {
  505. try
  506. {
  507. control.Invoke(action);
  508. }
  509. catch (Exception ex) when (ex is InvalidOperationException || ex is InvalidAsynchronousStateException)
  510. {
  511. // 忽略无效句柄操作
  512. Console.WriteLine("无法执行 Invoke:" + ex.Message);
  513. }
  514. }
  515. else
  516. {
  517. action();
  518. }
  519. }
  520. }
  521. public class DataLoader : IDisposable
  522. {
  523. private readonly BackgroundWorker _backgroundWorker;
  524. private ProgressDialog _progressDialog;
  525. private readonly Form _ownerForm;
  526. private readonly MyFunc<string> _delegateFunc;
  527. private Action<int, string> _onCompleted;
  528. private bool _disposed = false;
  529. public delegate int MyFunc<T>(object[] o, out T err, ProgressCallback progressCallback, ProgressMaxCallback progressMaxCallback, BackgroundWorker worker);
  530. public delegate void ProgressCallback(int progress);
  531. public delegate void ProgressMaxCallback(int max);
  532. public DataLoader(MyFunc<string> func, Form ownerForm)
  533. {
  534. _delegateFunc = func ?? throw new ArgumentNullException(nameof(func));
  535. _ownerForm = ownerForm;
  536. _backgroundWorker = new BackgroundWorker
  537. {
  538. WorkerReportsProgress = true,
  539. WorkerSupportsCancellation = true
  540. };
  541. _backgroundWorker.DoWork += BackgroundWorker_DoWork;
  542. _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
  543. _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
  544. }
  545. public void SetProgressBar(ProgressBarStyle style, string headerText, int mqSpeed)
  546. {
  547. if (_progressDialog == null || _progressDialog.IsDisposed)
  548. {
  549. _progressDialog = new ProgressDialog(_backgroundWorker)
  550. {
  551. PBStyle = style,
  552. HeaderText = headerText,
  553. MQSpeed = mqSpeed
  554. };
  555. }
  556. }
  557. public void Start(object[] args, Action<int, string> onCompleted)
  558. {
  559. if (_backgroundWorker.IsBusy) return;
  560. _onCompleted = onCompleted;
  561. if (_ownerForm == null || _ownerForm.IsDisposed)
  562. {
  563. _progressDialog?.Show();
  564. }
  565. else
  566. {
  567. _progressDialog?.Show(_ownerForm);
  568. }
  569. _backgroundWorker.RunWorkerAsync(args);
  570. }
  571. private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
  572. {
  573. //var args = (object[])e.Argument;
  574. //string errMsg = "";
  575. //int result = -1;
  576. //try
  577. //{
  578. // result = _delegateFunc(args, out errMsg,
  579. // progress => _backgroundWorker.ReportProgress(progress),
  580. // max => _progressDialog?.SetProgress(max));
  581. //}
  582. //catch (Exception ex)
  583. //{
  584. // errMsg = ex.Message;
  585. // result = 0;
  586. //}
  587. //e.Result = Tuple.Create(result, errMsg);
  588. var worker = sender as BackgroundWorker;
  589. if (worker == null)
  590. {
  591. e.Result = Tuple.Create(-1, "BackgroundWorker 实例无效");
  592. return;
  593. }
  594. var args = e.Argument as object[];
  595. if (args == null || args.Length == 0)
  596. {
  597. e.Result = Tuple.Create(-1, "参数无效");
  598. return;
  599. }
  600. string errMsg = "";
  601. int result = -1;
  602. try
  603. {
  604. // 定义进度报告的 Action
  605. ProgressCallback progressAction = percent =>
  606. {
  607. if (worker.WorkerReportsProgress && !worker.CancellationPending)
  608. worker.ReportProgress(percent);
  609. };
  610. // 定义设置最大值的 Action
  611. ProgressMaxCallback setProgressAction = max =>
  612. {
  613. if (_progressDialog != null && !_progressDialog.IsDisposed)
  614. _progressDialog.SetProgress(max);
  615. };
  616. // 调用实际业务逻辑
  617. result = _delegateFunc(args, out errMsg, progressAction, setProgressAction, _backgroundWorker);
  618. Global.writeLog($"result:{result}");
  619. }
  620. catch (Exception ex)
  621. {
  622. errMsg = $"后台任务发生异常: {ex.Message}";
  623. result = 0;
  624. }
  625. finally
  626. {
  627. Global.writeLog($"e.result:{e.Result}");
  628. }
  629. // 返回结果给 RunWorkerCompleted 事件
  630. e.Result = Tuple.Create(result, errMsg);
  631. Global.writeLog($"e.result2:{e.Result}");
  632. }
  633. private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  634. {
  635. //_progressDialog?.UpdateProgress(e.ProgressPercentage);
  636. _progressDialog.ProgressValue = (e.ProgressPercentage);
  637. }
  638. private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  639. {
  640. if (e.Cancelled)
  641. {
  642. MessageBox.Show("操作已取消");
  643. }
  644. else if (e.Error != null)
  645. {
  646. MessageBox.Show($"发生错误:{e.Error.Message}");
  647. }
  648. else
  649. {
  650. var resultTuple = (Tuple<int, string>)e.Result;
  651. _onCompleted?.Invoke(resultTuple.Item1, resultTuple.Item2);
  652. }
  653. _progressDialog?.Close();
  654. _progressDialog?.Dispose();
  655. _progressDialog = null;
  656. }
  657. #region IDisposable Support
  658. protected virtual void Dispose(bool disposing)
  659. {
  660. if (!_disposed)
  661. {
  662. if (disposing)
  663. {
  664. _backgroundWorker.Dispose();
  665. _progressDialog?.Dispose();
  666. }
  667. _disposed = true;
  668. }
  669. }
  670. public void Dispose()
  671. {
  672. Dispose(true);
  673. GC.SuppressFinalize(this);
  674. }
  675. #endregion
  676. }
  677. }