Clé*_*ent 7 mono multithreading invoke begininvoke
我正在使用单声道测试我的应用程序预装Linux端口,我有一个线程问题.我最初考虑在这里粘贴3000个代码行,但最后我设计了一个小的最小例子;)
你有一个带有按钮的表单(诗意地命名Button1,并且有一个标签(毫无意外地带有名称Label1)).整个地段都在一个叫做的形式上过着幸福的生活Form1.单击Button1启动无限循环,增加本地计数器并更新Label1(使用Invoke)以反映其值.
现在在Mono中,如果您调整表单大小,标签将停止更新,永远不会重新启动.MS实现不会发生这种情况.BeginInvoke没有更好的工作; 更糟糕的是,它使UI在两种情况下都挂起.
你知道这种差异来自哪里吗?你会如何解决它?最后,为什么BeginInvoke不在这里工作?我一定是犯了一个大错...但是哪个?
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)
这是单声道运行时的一个错误,至少我认为是这样.代码可能不是一个好的做法(我不是一个线程专家),但暗示一个错误的事实是Windows和Linux上的行为不同.
在Linux上,mono与MS.Net在Windows上的行为完全相同.即使在调整大小时也不会挂起,不断更新.
在Windows上,mono显示所有上述问题.我在https://bugzilla.novell.com/show_bug.cgi?id=690400上发布了一个错误报告.