gpt4 book ai didi

multithreading - 单声道挂起而 MS.Net 没有的线程问题

转载 作者:行者123 更新时间:2023-12-04 12:13:36 24 4
gpt4 key购买 nike

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

您有一个带有按钮的表单(诗意地命名为 Button1 和一个标签(毫不奇怪,它带有名称 Label1 ))。所有人都在一个名为 Form1 的表格上过着幸福的生活。 .点击 Button1启动一个无限循环,增加本地计数器并更新 Label1 (使用 Invoke )来反射(reflect)它的值(value)。

现在在 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

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

    最佳答案

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

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

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

    关于multithreading - 单声道挂起而 MS.Net 没有的线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5804076/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com