【问题标题】:Better approach for updating View components from Presenter, using MVP使用 MVP 从 Presenter 更新 View 组件的更好方法
【发布时间】:2018-05-30 13:05:07
【问题描述】:

我最近开始通过 MVP (PassiveView) 模式使用 WinForms 并坚持
“如何在演示者进行长时间(大约 20 秒)异步操作时让 View 自行更新”

所以我有一个表单,一个带有 UI 项的 IView 实现:

  • 一个Button,我的演示者通过Click事件订阅它;
  • 带有复选框列的DataGridView
  • 一个ProgressBar;
  • 和两个字段。 CurrentSelectedCount;

那我在那里做什么呢?
在那个Click 上,我的演示者从数据网格中抓取“已检查”项目并将它们写入数据库。
由于那个处理需要时间,我做了这个方法async

private async void PutToDatabase(List<Item> items)
{
    View.SelectedCount = items.Count;
    for (int i = 0; i < items.Count; i++)
    {
        await Task.Factory.StartNew(
         () =>
            {
                // writing stuff to database via ADO.NET
                View.Current = i;
            });
    }
}

所以我正在更新我的 Current,它通过这样做来更新我的 progressBar:

public int CurrentPrice
{
    get { return _current; }
    set
    {
        _current = value;
        Invoke((MethodInvoker) delegate {progBarImportState.Value = _current; });
    }
}

我不确定这种方法是否能正常工作,因为我无法重新加载我的 UI 以再次使用表单,除非我要检查 somwhere(例如在同一个委托中)if progress.value == progress.maximum 并回滚表单以重用它。加, 它看起来并不“漂亮”。

那么还有比这更有效/更清洁的解决方案吗?

【问题讨论】:

    标签: c# winforms async-await mvp


    【解决方案1】:

    你为什么不使用后台工人,很老派,但炒锅很好。 Click here 了解有关后台工作人员的更多信息。您可以像这样使用 Background-Worker:

    private void Main(string[] args)
    {
        BackgroundWorker bw = new BackgroundWorker();
        bw.DoWork += Bw_DoWork;
        bw.RunWorkerCompleted += Bw_RunWorkerCompleted;
    
        //Parameter you need to work in Background-Thread for example your strings
        string[] param = new[] {"Text1", "Text2", "Text3", "Text4"};
    
        //Start work
        bw.RunWorkerAsync(param);
    }
    
    //Do your Background-Work
    private void Bw_DoWork(object sender, DoWorkEventArgs e)
    {
        string[] param = e.Argument as string[];
    
        //Process your long running  task
    
        e.Result = null; //Set your Result of the long running task
    }
    
    //Taking your results
    private void Bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //Apply your Results to your GUI-Elements
        myTextBox1.Text = e.Result.ToString();
    }
    

    【讨论】:

    • 如您所见,我已经在 Presenter 中使用 Tasks 并更新其中的模型字段。如果你建议在视图中使用 BGW,它会挂起 UI。
    猜你喜欢
    • 2011-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多