单声道挂起且MS.Net不会出现的线程问题 [英] A threading problem where mono hangs and MS.Net doesn't

查看:78
本文介绍了单声道挂起且MS.Net不会出现的线程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在预配置Linux端口时用mono测试我的应用程序,但是我遇到了线程问题.我最初考虑在此处粘贴3000条代码行,但最终我设计了一个小小的示例;)

I'm testing my app with mono in prevision of a Linux port, and I have a threading problem. I initially considered pasting 3000 code lines here, but finally I've devised a small minimal example ;)

您有一个带有按钮的窗体(通常命名为Button1)和标签(带有标签(毫无疑问地带有名称Label1)).整个过程都以称为Form1的形式过着幸福的生活.单击Button1将启动无限循环,该循环将递增本地计数器并更新Label1(使用Invoke)以反映其值.

You have a form with a button (poetically named Button1, and a label (which bears, without surprise, the name Label1)). The whole lot is living a happy life on a form called Form1. Clicking Button1 launches an infinite loop that increments a local counter and updates Label1 (using Invoke) to reflect its value.

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

Now in Mono, if you resize the form, the label stops updating, never to restart. This doesn't happen with MS implementation. BeginInvoke doesn't work any better; worse, it makes the UI hang in both cases.

您知道这种差异来自何处吗?您将如何解决?最后,为什么BeginInvoke在这里不起作用?我一定是犯了个大错误...但是哪个呢?

Do you know where this discrepancy comes from? How would you solve it? And finally, why doesn't BeginInvoke work here? I must be making a huge mistake... but which?


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


EDIT: Some progress so far:

  • 实际上,调用BeginInvoke确实可以;只是,UI的刷新速度不够快,因此似乎停止了.
  • 在mono上,发生的事情是当您在UI队列中插入一条消息时整个线程挂起(例如,通过调整表单大小).实际上,同步Invoke调用永不返回.我正试图了解原因.
  • 有趣的是:即使使用BeginInvoke,在调整大小操作结束之前,异步调用也不会执行.在MS.Net上,它们在调整大小的同时保持运行.
  • Calling BeginInvoke does in fact work; only, the UI just doesn't refresh fast enough, so it seems to stop.
  • On mono, what happens is that the whole thread hangs when you insert a message in the UI queue (eg by resizing the form). In fact, the synchronous Invoke call never returns. I'm trying to understand why.
  • Of interest: even using BeginInvoke, the asynchronous calls don't get executed before the resizing operation ends. On MS.Net, they keep running while resizing.

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

The code looks like this (C# version lower):

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

或者,在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) {
        }
    }
}

推荐答案

这是mono运行时中的错误,至少我认为是.代码可能不是一个好习惯(我不是线程专家),但是提示错误的原因是Windows和Linux上的行为不同.

This is a bug in the mono runtime, at least I think it is. The code might not be good practice (I'm not a threading expert), but the thing that suggests a bug is the fact that the behaviour differs on windows and Linux.

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

On Linux, mono has exactly the same behaviour as MS.Net has on windows. No hanging, continuous updates even while resizing.

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

On Windows, mono displays all the aforementioned problems. I've posted a bug report at https://bugzilla.novell.com/show_bug.cgi?id=690400 .

这篇关于单声道挂起且MS.Net不会出现的线程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆