单声道挂起和MS.Net没有的线程问题

Clé*_*ent 7 mono multithreading invoke begininvoke

我正在使用单声道测试我的应用程序预装Linux端口,我有一个线程问题.我最初考虑在这里粘贴3000个代码行,但最后我设计了一个小的最小例子;)

你有一个带有按钮的表单(诗意地命名Button1,并且有一个标签(毫无意外地带有名称Label1)).整个地段都在一个叫做的形式上过着幸福的生活Form1.单击Button1启动无限循环,增加本地计数器并更新Label1(使用Invoke)以反映其值.

现在在Mono中,如果您调整表单大小,标签将停止更新,永远不会重新启动.MS实现不会发生这种情况.BeginInvoke没有更好的工作; 更糟糕的是,它使UI在两种情况下都挂起.

你知道这种差异来自哪里吗?你会如何解决它?最后,为什么BeginInvoke不在这里工作?我一定是犯了一个大错...但是哪个?


编辑:到目前为止取得了一些进展:

  • 调用BeginInvoke确实可以工作; 只是,UI只是没有足够快地刷新,所以它似乎停止了.
  • 在单声道上,当您在UI队列中插入消息时(例如通过调整表单大小),整个线程会挂起.实际上,同步Invoke调用永远不会返回.我想知道为什么.
  • 有趣的是:即使使用BeginInvoke,在调整大小操作结束之前也不会执行异步调用.在MS.Net上,它们在调整大小时继续运行.

代码看起来像这样(C#版本更低):

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim T As New Threading.Thread(AddressOf Increment)
        T.Start()
    End Sub

    Sub UpdateLabel(ByVal Text As String)
        Label1.Text = Text
    End Sub

    Delegate Sub UpdateLabelHandler(ByVal Text As String)
    Sub Increment()
        Dim i As Long = 0
        Dim UpdateLabelDelegate As New UpdateLabelHandler(AddressOf UpdateLabel)
        Try
            While True
                i = (i + 1) Mod (Long.MaxValue - 1)
                Me.Invoke(UpdateLabelDelegate, New Object() {i.ToString})
            End While
        Catch Ex As ObjectDisposedException
        End Try
    End Sub
End Class
Run Code Online (Sandbox Code Playgroud)

或者,在C#中,

public class Form1
{
    private void Button1_Click(System.Object sender, System.EventArgs e)
    {
        System.Threading.Thread T = new System.Threading.Thread(Increment);
        T.Start();
    }

    public void UpdateLabel(string Text)
    {
        Label1.Text = Text;
    }

    public delegate void UpdateLabelHandler(string Text);
    public void Increment()
    {
        long i = 0;
        UpdateLabelHandler UpdateLabelDelegate = new UpdateLabelHandler(UpdateLabel);
        try {
            while (true) {
                i = (i + 1) % (long.MaxValue - 1);
                this.Invoke(UpdateLabelDelegate, new object[] { i.ToString() });
            }
        } catch (ObjectDisposedException Ex) {
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Clé*_*ent 5

这是单声道运行时的一个错误,至少我认为是这样.代码可能不是一个好的做法(我不是一个线程专家),但暗示一个错误的事实是Windows和Linux上的行为不同.

在Linux上,mono与MS.Net在Windows上的行为完全相同.即使在调整大小时也不会挂起,不断更新.

在Windows上,mono显示所有上述问题.我在https://bugzilla.novell.com/show_bug.cgi?id=690400上发布了一个错误报告.