【问题标题】:C# Synchronisation with screen updatesC# 与屏幕更新同步
【发布时间】:2011-02-09 11:37:29
【问题描述】:

我有以下问题: 我的应用程序进行了屏幕更新,之后应该制作新视图的屏幕截图。
代码如下:

    public ViewModelBase Screen {
        get {
            if (_screen == null) {
                Screen = new DataSourceChooserScreenViewModel(this);
                History.ChangeHistory(ADD_ITEM);
            }
            return _screen;
        }
        set {
            _screen = value;
            OnPropertyChanged("Screen");

            System.Windows.Forms.Application.DoEvents();
        }
    }

屏幕更新在“OnPropertyChanged("Screen")”中完成,屏幕截图在“History.ChangeHistory(ADD_ITEM)”中进行。
调用“屏幕”设置器的方法遵循所有相同的方案:

//Do something
Screen = otherScreen;
History.ChangeHistory(ADD_ITEM);
//Do something else

这就是问题所在: 屏幕截图是在屏幕更新之前制作的,尽管执行顺序另有说明。

为了自己解决问题,我尝试了几件事:
正在 ADD_ITEM 中等待
通过 ADD_ITEM 中的计时器等待
通过 BeginInvoke() 和 EndInvoke() 等待 PropertyChangedEvent 使用异步线程
System.Windows.Forms.Application.DoEvents() 的用法

所有尝试都有相同的结果:屏幕截图是在屏幕更新之前完成的。在尝试使用计时器时,我发现屏幕会在 ADD_ITEM 执行后更新。所以我建议编译器做一些隐式线程,我不知道如何修复/防止它。

感谢您的帮助。

【问题讨论】:

  • 对不起,愚蠢的假设......你有没有在截图前尝试使用 System.Windows.Forms.Application.DoEvents() 几次?
  • 另外,尝试在另一个线程中制作屏幕截图。先调用 DoEvents 再通过 ThreadPool.QueUserWorkItem 启动新线程

标签: c# winforms view synchronisation


【解决方案1】:

当我必须做类似的事情时,我总是使用计时器事件,该事件将在处理完所有内容后触发。这将是一次性计时器事件,用法如下:

发射它:

Timer t=new Timer();
t.Tick+=DoAfter;
t.Interval=100;
t.Start();

需要做的就在这里:

void DoAfter(object Sender, SomeArgs a)
{
    Timer t=(Timer)Sender;
    t.Stop();
    t.Dispose();
    //  perform your stuff here
    DoStuff();
}

这样,您很有可能消息循环将完成所有操作,并且屏幕更新将在计时器触发之前完成。

【讨论】:

  • 如果您使用的是System.Windows.Forms.Timer,则可以保证它已完成绘制。它在后台解析为WM_TIMER,这是Windows 中最低的“优先级”消息。它由GetMessage 合成,如果有一个计时器已经过去,如果没有其他事情可做。
猜你喜欢
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 2018-11-17
  • 1970-01-01
相关资源
最近更新 更多