Winforms异步更新UI模式

编程入门 行业动态 更新时间:2024-10-24 01:53:53
Winforms异步更新UI模式 - 需要概括(Winforms Updating UI Asynchronously Pattern - Need to Generalize)

设置:带有进度条和标签的主MDI表单。

主表格中的代码。

public delegate void UpdateMainProgressDelegate(string message, bool isProgressBarStopped); private void UpdateMainProgress(string message, bool isProgressBarStopped) { // make sure we are running on the right thread to be // updating this form's controls. if (InvokeRequired == false) { // we are running on the right thread. Have your way with me! bsStatusMessage.Caption = message + " [ " + System.DateTime.Now.ToShortTimeString() + " ]"; progressBarStatus.Stopped = isProgressBarStopped; } else { // we are running on the wrong thread. // Transfer control to the correct thread! Invoke(new ApplicationLevelValues.UpdateMainProgressDelegate(UpdateMainProgress), message, isProgressBarStopped); } }

儿童表格

private readonly ApplicationLevelValues.UpdateMainProgressDelegate _UpdateMainForm; private void btnX_Click(object sender, EventArgs e) { _UpdateMainForm.BeginInvoke("StartA", false, null, null); try { if(UpdateOperationA()) { _UpdateMainForm.BeginInvoke("CompletedA", true, null, null); } else { _UpdateMainForm.BeginInvoke("CanceledA", true, null, null); } } catch (System.Exception ex) { _UpdateMainForm.BeginInvoke("ErrorA", true, null, null); throw ex; } }

它的工作非常好,但是对于N按钮或N个操作,我必须一次又一次地编写相同的代码。 有没有什么方法可以推广或更新UI的任何其他更好的方法。

Setup: Main MDI form with a progress bar and a label.

Code in Main form.

public delegate void UpdateMainProgressDelegate(string message, bool isProgressBarStopped); private void UpdateMainProgress(string message, bool isProgressBarStopped) { // make sure we are running on the right thread to be // updating this form's controls. if (InvokeRequired == false) { // we are running on the right thread. Have your way with me! bsStatusMessage.Caption = message + " [ " + System.DateTime.Now.ToShortTimeString() + " ]"; progressBarStatus.Stopped = isProgressBarStopped; } else { // we are running on the wrong thread. // Transfer control to the correct thread! Invoke(new ApplicationLevelValues.UpdateMainProgressDelegate(UpdateMainProgress), message, isProgressBarStopped); } }

Child Form

private readonly ApplicationLevelValues.UpdateMainProgressDelegate _UpdateMainForm; private void btnX_Click(object sender, EventArgs e) { _UpdateMainForm.BeginInvoke("StartA", false, null, null); try { if(UpdateOperationA()) { _UpdateMainForm.BeginInvoke("CompletedA", true, null, null); } else { _UpdateMainForm.BeginInvoke("CanceledA", true, null, null); } } catch (System.Exception ex) { _UpdateMainForm.BeginInvoke("ErrorA", true, null, null); throw ex; } }

Its working pretty fine, but for N buttons or N operations I have to write the same code again and again. Is there any way this can be generalized or any other better way to update the UI.

最满意答案

如果您的操作都可以表示为单个委托类型,那么这实际上只是一个简单的重构问题。 例如:

private void RunOperationWithMainProgressFeedback( Func<bool> operation, string startMessage, string completionMessage, string cancellationMessage, string errorMessage) { this._UpdateMainForm.BeginInvoke(startMessage, false, null, null); try { if (operation.Invoke()) { this._UpdateMainForm.BeginInvoke(completionMessage, true, null, null); } else { this._UpdateMainForm.BeginInvoke(cancellationMessage, true, null, null); } } catch (Exception) { this._UpdateMainForm.BeginInvoke(errorMessage, true, null, null); throw; } } private void btnX_Click(object sender, EventArgs e) { this.RunOperationWithMainProgressFeedback( this.UpdateOperationA, "StartA", "CompletedA", "CanceledA", "ErrorA"); }

虽然可以使用字典来存储参数值(如VinayC早期的答案所示),但这不是必需的。 就个人而言,我会因为可读性和性能原因而避免使用它,但是ymmv ......

This is really just a simple refactoring problem if your operations can all be represented as a single delegate type. e.g.:

private void RunOperationWithMainProgressFeedback( Func<bool> operation, string startMessage, string completionMessage, string cancellationMessage, string errorMessage) { this._UpdateMainForm.BeginInvoke(startMessage, false, null, null); try { if (operation.Invoke()) { this._UpdateMainForm.BeginInvoke(completionMessage, true, null, null); } else { this._UpdateMainForm.BeginInvoke(cancellationMessage, true, null, null); } } catch (Exception) { this._UpdateMainForm.BeginInvoke(errorMessage, true, null, null); throw; } } private void btnX_Click(object sender, EventArgs e) { this.RunOperationWithMainProgressFeedback( this.UpdateOperationA, "StartA", "CompletedA", "CanceledA", "ErrorA"); }

While it's possible to use a dictionary to store the argument values (as suggested in VinayC's earlier answer), this isn't necessary. Personally, I would avoid it for both readability and performance reasons, but ymmv...

更多推荐

本文发布于:2023-07-16 12:40:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1128562.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:模式   Winforms   UI

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!