鼠标移动和线程

时间:2011-01-01 03:01:50

标签: c# multithreading macos mono mouse

当我将鼠标移到窗口上时,程序运行得更快(cc.3次)。这是在MacBook上运行的实时网络摄像头.Net / Mono应用程序。在Windows上完美运行。这可能是笔记本电脑的省电功能吗?代码:

Thread t = new Thread(Foo);
t.Priority = ThreadPriority.Highest; // I've tried without priority too, doesn't matter
t.Start();
...
delegate void SetInt(int k);
void Foo()
{
    int k = 0;
    while (true)
    {
        ++k; 
        BeginInvoke(new SetInt(Bar), k);   
    }
}
void Bar(int k)
{
    Graphics.FromImage(pictureBox1.Image).DrawString(k.ToString(),
        System.Fonts.DefaultFont, Brushes.Red, 0, 0);
    pictureBox1.Invalidate();
}

我看k的价值。它每秒增加10-30次,具体取决于鼠标移动。看起来UI线程阻塞了工作线程?工作线程应该在一秒内增加k00万次。

编辑: Miguel de Icaza怀疑这是Mono中的一个错误。我把它上传到Mono的bugtracker: https://bugzilla.novell.com/show_bug.cgi?id=663433 附有测试用例。现在我正在寻找一个黑客来避免这个问题。

3 个答案:

答案 0 :(得分:2)

不同的操作系统以不同的方式处理线程优先级,并且您不能依赖它们在不同的操作系统上以相同的方式工作。您甚至不能依赖它们在不同的虚拟机(Mono vs .net)上以相同的方式工作,因为这些是依赖于操作系统的值,而不是由规范真正定义。

答案 1 :(得分:1)

我调查了这一点,并相信我找到了一个解决方法。我在Mono上运行的C#.Net程序遇到了同样的问题,其中消息没有在线程中处理。似乎问题是线程没有被调用或等待事件。我找到的工作如下。

1)创建表单事件(注意它与System.Timers不同)

private System.Windows.Forms.Timer timerForMonoResponsiveness;

2)在构造函数或初始化

中设置表单事件
// This is a fix for mono not updating messages until an event (such as movement of
// the mouse) happens
// We use an event timer to fire off an event on a regular basis.
// This calls a function that doesn't do anything.
if (Type.GetType("Mono.Runtime") != null) // Only run if in Mono
{
    this.timerForMonoResponsiveness = new System.Windows.Forms.Timer(this.components);
    this.timerForMonoResponsiveness.Interval = 100;
    this.timerForMonoResponsiveness.Tick += new EventHandler(timertimerForMonoResponsiveness_Tick);
    this.timerForMonoResponsiveness.Start();
}

注意:“ this.components ”在表单的 Form.designer.cs 中定义(应该自动完成)我的看起来像这样:

private System.ComponentModel.IContainer components = null;

初始化为:

this.components = new System.ComponentModel.Container();

3)为计时器

创建计时功能
// This function executes a Tick event so the UI updates on Mono
// This is a Mono bug workaround as the message processing was not being processed
// and was waiting on invoke which on Mono only runs when a UI element is changed (or  
// the mouse is moved). This function therefore runs regularly to mitigate this issue 
// it is called within a Mono check and will not run on Windows
// The function is SUPPOSED TO DO NOTHING.

private void timerForMonoResponsiveness_Tick(object sender, EventArgs e)
{
    this.timerMonoEventForMessagesToBeUpdated.Stop();
    // This doesn't need to do anything, just call the event
    this.timerMonoEventForMessagesToBeUpdated.Start();          
}

希望这有帮助。

答案 2 :(得分:0)

考虑到你在Mac上运行Mono,我认为CLR没有获得完全优先级,或者线程没有获得完全优先级。在这里我同意mystere man,你的优先权陈述可能没有达到预期的效果。

此外,Windows 7似乎优化了前台进程,以便为它们提供更高的优先级,因此UI看起来响应更快,并且mac OS可能会做得太多。因此,当您的应用程序中发生活动时(鼠标移动和键盘按下),您的应用程序将获得更多的处理器时间..

可能是Mono没有处理优先级,或者somethign正在改变运行时的优先级(OS iteself)。