c# - Winforms 异步更新 UI 模式 - 需要概括

标签 c# winforms user-interface asynchronous progress-bar

设置:带有进度条和标签的主 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。

最佳答案

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

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...

关于c# - Winforms 异步更新 UI 模式 - 需要概括,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3582140/

相关文章:

c# - 如何使用 100% CPU 修复单声道?

c# - 从 wpf 资源绑定(bind)文本 block 文本

c# - 从 IDE 调试项目但在 IDE 外部运行时未捕获异常

python - 如何在 Tkinter 中更改 simpledialog 的焦点?

c# - 使用 Ghostscript 从 PDF 裁剪页脚

c# - 缺少必需的参数 '<PROVIDER>'。 ASP.NET Core 2.1.MAC中的Scaffold Dbcontext

c# - 如何禁用C#中的最小化按钮?

java - 少数 ASCII 字符在 Windows 应用程序中不起作用

javascript - Meteor 0.8.0+,如何为长时间运行的代码提供 'busy spinner'?

python - 使用 tkinter 的简单动画