C# 鼠标移动和线程

C# 鼠标移动和线程,c#,multithreading,macos,mono,mouse,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

当我将鼠标移到窗口上时,程序运行得更快(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线程阻止了工作线程?工作线程应在一秒内增加k百万次

编辑:Miguel de Icaza怀疑这是Mono中的一个bug。我把它上传到Mono的bugtracker上:
附测试用例。现在我正在寻找一种方法来避免这个问题。

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

不同的操作系统对待线程优先级的方式不同,您不能依赖它们在不同的操作系统上以相同的方式工作。你甚至不能指望它们在不同的虚拟机上以相同的方式工作(Mono与.net),因为它们是依赖于操作系统的值,并不是由规范真正定义的。

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

此外,Windows 7似乎优化了前台进程,赋予它们更高的优先级,因此UI似乎更具响应性,而mac OS可能做得太多了。因此,当应用程序中发生活动时(鼠标移动和键盘按下),应用程序将获得更多的处理器时间


可能是Mono没有处理优先级,或者某个东西在运行时更改了您的优先级(操作系统本身)。

考虑到您在mac上的Mono上运行此程序,我认为CLR没有获得完全优先级,或者线程没有获得完全优先级。在这里我同意mystere man的观点,你的优先权声明可能没有达到预期的效果

此外,Windows 7似乎优化了前台进程,赋予它们更高的优先级,因此UI似乎更具响应性,而mac OS可能做得太多了。因此,当应用程序中发生活动时(鼠标移动和键盘按下),应用程序将获得更多的处理器时间


可能是Mono没有处理优先级,或者在运行时有什么东西改变了您的优先级(操作系统本身)。

我对此进行了研究,相信我已经找到了解决方法。我在Mono上运行的C#.Net程序中遇到了同样的问题,在该程序中,消息没有在线程中处理。问题似乎在于线程没有被调用或等待事件。我发现的工作如下

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

private System.Windows.Forms.Timer Timer for mono响应

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();          
}

希望这能有所帮助。

我对此进行了调查,相信我已经找到了解决办法。我在Mono上运行的C#.Net程序中遇到了同样的问题,在该程序中,消息没有在线程中处理。问题似乎在于线程没有被调用或等待事件。我发现的工作如下

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

private System.Windows.Forms.Timer Timer for mono响应

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();          
}

希望这有帮助。

“程序运行得更快”-如何衡量?你的意思是你得到更频繁的用户界面更新吗?我注意k的值。也许不是更快,只是线程更频繁地处于活动状态?此外,这个线程不是UI,而是一个新的工作线程。“程序运行得更快”-如何衡量?你的意思是你得到更频繁的用户界面更新吗?我注意k的值。也许不是更快,只是线程更频繁地处于活动状态?而且这个线程不是UI,它是一个新的工作线程。