【问题标题】:Window.Show() doesn't display controls but Window.ShowDialog() does 2Window.Show() 不显示控件,但 Window.ShowDialog() 显示 2
【发布时间】:2015-06-17 22:44:01
【问题描述】:

我已经这样做了Window.Show() doesn't display controls but Window.ShowDialog() does 来解决问题。但尽管如此,我也有同样的问题。如何修改下面的代码来解决这个问题?

            TimeWindow aTimeWindow = new TimeWindow();
            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += ((o, ea) => { 
                // Highly time consumable task
                _resetEvent.Set();
            });
            aTimeWindow.Show();
            bw.RunWorkerAsync();
            _resetEvent.WaitOne();
            aTimeWindow.Close();

_resetEvent 是类的一个字段。 TimeWindow 只是带​​有TextBox WPF 控件的图像。

【问题讨论】:

  • 你仍然在阻塞,而不是使用重置事件,只需在工作完成后关闭DoWork委托的时间窗口。

标签: c# wpf windows xaml


【解决方案1】:

您可以只异步/等待,以便在工作完成时显示和关闭窗口。比如:

private async void ShowWindow()
{
    var aTimeWindow = new TimeWindow();
    aTimeWindow.Show();
    await Task.Run((Action)DoWork);
    aTimeWindow.Close();    
}

private void DoWork()
{
    // perform long running work here
}

编辑:

不使用异步/等待

private void ShowWindow()
{
    var aTimeWindow = new TimeWindow();
    aTimeWindow.Show();

    Task.Run(()=>
    {
        DoWork();
    })
    .ContinueWith((t) =>
    {       
        Application.Current.Dispatcher.BeginInvoke((Action)(() => 
        {
            aTimeWindow.Close();    
        }));
    });
}

private void DoWork()
{
    // perform long running work here
}

【讨论】:

  • 将 Task.Run 包装为整个方法被认为是“不好的做法”,更好的方法是在 ShowWindow 中执行 await Task.Run(DoWork); 然后将 DoWork 设为 private void DoWork()。此外,async void 应该只支持 EventHandlers,ShowWindow 应该真正返回一个Task。 (-1 用于async void,修复它,我会删除它。修复 DoWork,它甚至可能变成 +1)
  • 我从来没有听说过这是不好的做法。介意解释为什么?你引起了我的兴趣。 =]
  • 基本上你正在为同步方法制作一个异步包装器,所以我推荐 MSDN 文章“Should I expose asynchronous wrappers for synchronous methods?”。基本总结:不,让调用者将函数调用包装在 Task.Run 中,或者更好地公开你的方法的真正异步版本......
  • 现在因为 DoWork 是私有的,这并不重要,但我敢打赌 OP 对异步编程来说是新的,最好向新程序员展示良好实践,即使在那些实践无关紧要的领域也是如此因为他们往往不知道背后的原因,也不知道什么时候可以不使用“好的模式”
  • 谢谢大家的回复。所以这个决定适用于 C# 5。但我只有 4 个版本。是否有另一种方法来执行异步行为? PS。我使用了 Thread.Run/Join ,但这给了我与使用 BW 相同的行为。
猜你喜欢
  • 1970-01-01
  • 2011-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多