ProgressHelper.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782
  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. public class ProgressDialog : Form
  378. {
  379. private ProgressBar _progressBar;
  380. private Label _labelStatus;
  381. private Button _cancelButton;
  382. private BackgroundWorker _backgroundWorker;
  383. private int _maximum = 100;
  384. private string _header = "正在查询...";
  385. public string HeaderText
  386. {
  387. get => _header;
  388. set { Text = _header = value; }
  389. }
  390. public ProgressBarStyle PBStyle
  391. {
  392. get => _progressBar.Style;
  393. set => _progressBar.Style = value;
  394. }
  395. public int MQSpeed
  396. {
  397. get => _progressBar.MarqueeAnimationSpeed;
  398. set => _progressBar.MarqueeAnimationSpeed = value;
  399. }
  400. public ProgressDialog()
  401. {
  402. InitializeComponent();
  403. }
  404. public ProgressDialog(BackgroundWorker backgroundWorker) : this()
  405. {
  406. _backgroundWorker = backgroundWorker;
  407. }
  408. private void InitializeComponent()
  409. {
  410. Application.EnableVisualStyles();
  411. // 设置窗体样式
  412. Text = _header;
  413. StartPosition = FormStartPosition.CenterParent;
  414. FormBorderStyle = FormBorderStyle.FixedDialog;
  415. MaximizeBox = false;
  416. MinimizeBox = false;
  417. ShowInTaskbar = false;
  418. TopMost = true;
  419. ClientSize = new Size(284, 100);
  420. CenterToScreen();
  421. // 初始化进度条
  422. _progressBar = new ProgressBar
  423. {
  424. Location = new Point(12, 12),
  425. Size = new Size(260, 23),
  426. Style = ProgressBarStyle.Marquee,
  427. MarqueeAnimationSpeed = 50
  428. };
  429. Controls.Add(_progressBar);
  430. // 状态标签
  431. _labelStatus = new Label
  432. {
  433. Location = new Point(12, 41),
  434. Size = new Size(260, 23)
  435. };
  436. Controls.Add(_labelStatus);
  437. // 取消按钮
  438. _cancelButton = new Button
  439. {
  440. Text = "取消",
  441. Location = new Point(197, 60),
  442. Size = new Size(75, 23)
  443. };
  444. _cancelButton.Click += CancelButton_Click;
  445. Controls.Add(_cancelButton);
  446. SetStyle(ControlStyles.ResizeRedraw, true);
  447. }
  448. public int ProgressValue
  449. {
  450. set
  451. {
  452. if (this.IsHandleCreated)
  453. {
  454. this.InvokeIfRequired(() =>
  455. {
  456. _progressBar.Value = value;
  457. _labelStatus.Text = $"已完成 {value}/{_maximum}";
  458. if (value == _maximum || value >= _progressBar.Maximum)
  459. {
  460. _progressBar.Refresh();
  461. _labelStatus.Refresh();
  462. }
  463. });
  464. }
  465. }
  466. }
  467. public void SetProgress(int max)
  468. {
  469. _maximum = max;
  470. _progressBar.Maximum = max;
  471. }
  472. public string StatusText
  473. {
  474. set => this.InvokeIfRequired(() => _labelStatus.Text = value);
  475. }
  476. private void CancelButton_Click(object sender, EventArgs e)
  477. {
  478. if (_backgroundWorker != null && _backgroundWorker.WorkerSupportsCancellation)
  479. {
  480. _backgroundWorker.CancelAsync();
  481. }
  482. this.Close();
  483. }
  484. public async void ShowAsync()
  485. {
  486. await Task.Run(() =>
  487. {
  488. Application.Run(this);
  489. });
  490. }
  491. protected override void OnClosed(EventArgs e)
  492. {
  493. base.OnClosed(e);
  494. _backgroundWorker = null;
  495. }
  496. }
  497. // 扩展方法:简化 Invoke 操作
  498. public static class ControlExtensions
  499. {
  500. public static void InvokeIfRequired(this Control control, MethodInvoker action)
  501. {
  502. if (control.InvokeRequired)
  503. {
  504. try
  505. {
  506. control.Invoke(action);
  507. }
  508. catch (Exception ex) when (ex is InvalidOperationException || ex is InvalidAsynchronousStateException)
  509. {
  510. // 忽略无效句柄操作
  511. Console.WriteLine("无法执行 Invoke:" + ex.Message);
  512. }
  513. }
  514. else
  515. {
  516. action();
  517. }
  518. }
  519. }
  520. public class DataLoader : IDisposable
  521. {
  522. private readonly BackgroundWorker _backgroundWorker;
  523. private ProgressDialog _progressDialog;
  524. private readonly Form _ownerForm;
  525. private readonly MyFunc<string> _delegateFunc;
  526. private Action<int, string> _onCompleted;
  527. private bool _disposed = false;
  528. public delegate int MyFunc<T>(object[] o, out T err, ProgressCallback progressCallback, ProgressMaxCallback progressMaxCallback, BackgroundWorker worker);
  529. public delegate void ProgressCallback(int progress);
  530. public delegate void ProgressMaxCallback(int max);
  531. public DataLoader(MyFunc<string> func, Form ownerForm)
  532. {
  533. _delegateFunc = func ?? throw new ArgumentNullException(nameof(func));
  534. _ownerForm = ownerForm;
  535. _backgroundWorker = new BackgroundWorker
  536. {
  537. WorkerReportsProgress = true,
  538. WorkerSupportsCancellation = true
  539. };
  540. _backgroundWorker.DoWork += BackgroundWorker_DoWork;
  541. _backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
  542. _backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
  543. }
  544. public void SetProgressBar(ProgressBarStyle style, string headerText, int mqSpeed)
  545. {
  546. if (_progressDialog == null || _progressDialog.IsDisposed)
  547. {
  548. _progressDialog = new ProgressDialog(_backgroundWorker)
  549. {
  550. PBStyle = style,
  551. HeaderText = headerText,
  552. MQSpeed = mqSpeed
  553. };
  554. }
  555. }
  556. public void Start(object[] args, Action<int, string> onCompleted)
  557. {
  558. if (_backgroundWorker.IsBusy) return;
  559. _onCompleted = onCompleted;
  560. if (_ownerForm == null || _ownerForm.IsDisposed)
  561. {
  562. _progressDialog?.Show();
  563. }
  564. else
  565. {
  566. _progressDialog?.Show(_ownerForm);
  567. }
  568. _backgroundWorker.RunWorkerAsync(args);
  569. }
  570. private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
  571. {
  572. //var args = (object[])e.Argument;
  573. //string errMsg = "";
  574. //int result = -1;
  575. //try
  576. //{
  577. // result = _delegateFunc(args, out errMsg,
  578. // progress => _backgroundWorker.ReportProgress(progress),
  579. // max => _progressDialog?.SetProgress(max));
  580. //}
  581. //catch (Exception ex)
  582. //{
  583. // errMsg = ex.Message;
  584. // result = 0;
  585. //}
  586. //e.Result = Tuple.Create(result, errMsg);
  587. var worker = sender as BackgroundWorker;
  588. if (worker == null)
  589. {
  590. e.Result = Tuple.Create(-1, "BackgroundWorker 实例无效");
  591. return;
  592. }
  593. var args = e.Argument as object[];
  594. if (args == null || args.Length == 0)
  595. {
  596. e.Result = Tuple.Create(-1, "参数无效");
  597. return;
  598. }
  599. string errMsg = "";
  600. int result = -1;
  601. try
  602. {
  603. // 定义进度报告的 Action
  604. ProgressCallback progressAction = percent =>
  605. {
  606. if (worker.WorkerReportsProgress && !worker.CancellationPending)
  607. worker.ReportProgress(percent);
  608. };
  609. // 定义设置最大值的 Action
  610. ProgressMaxCallback setProgressAction = max =>
  611. {
  612. if (_progressDialog != null && !_progressDialog.IsDisposed)
  613. _progressDialog.SetProgress(max);
  614. };
  615. // 调用实际业务逻辑
  616. result = _delegateFunc(args, out errMsg, progressAction, setProgressAction,_backgroundWorker);
  617. }
  618. catch (Exception ex)
  619. {
  620. errMsg = $"后台任务发生异常: {ex.Message}";
  621. result = 0;
  622. }
  623. // 返回结果给 RunWorkerCompleted 事件
  624. e.Result = Tuple.Create(result, errMsg);
  625. }
  626. private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
  627. {
  628. //_progressDialog?.UpdateProgress(e.ProgressPercentage);
  629. _progressDialog.ProgressValue = (e.ProgressPercentage);
  630. }
  631. private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  632. {
  633. if (e.Cancelled)
  634. {
  635. MessageBox.Show("操作已取消");
  636. }
  637. else if (e.Error != null)
  638. {
  639. MessageBox.Show($"发生错误:{e.Error.Message}");
  640. }
  641. else
  642. {
  643. var resultTuple = (Tuple<int, string>)e.Result;
  644. _onCompleted?.Invoke(resultTuple.Item1, resultTuple.Item2);
  645. }
  646. _progressDialog?.Close();
  647. _progressDialog?.Dispose();
  648. _progressDialog = null;
  649. }
  650. #region IDisposable Support
  651. protected virtual void Dispose(bool disposing)
  652. {
  653. if (!_disposed)
  654. {
  655. if (disposing)
  656. {
  657. _backgroundWorker.Dispose();
  658. _progressDialog?.Dispose();
  659. }
  660. _disposed = true;
  661. }
  662. }
  663. public void Dispose()
  664. {
  665. Dispose(true);
  666. GC.SuppressFinalize(this);
  667. }
  668. #endregion
  669. }
  670. }