. net WinForms多线程行为:在ThreadPool中设置属性值.QueueUserWorkItem,尽管例外
本文关键字:QueueUserWorkItem 属性 设置 多线程 WinForms ThreadPool net | 更新日期: 2023-09-27 18:13:49
今天碰到这个代码示例:
private void Form1_Load(object sender, EventArgs e)
{
try
{
ThreadPool.QueueUserWorkItem(ShowMessage, null);
}
catch
{
}
}
private void ShowMessage(object obj)
{
try
{
label1.Text = "Test"; // does't work and just goes into catch block
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
try
{
button1.Text = "Test"; // will actually set Text property of a button and only then throw an exception, which will be caught in corresponding catch block
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
}
}
我知道应该使用Invoke来处理控件的属性。什么让我困惑的是,为什么它实际上改变文本字段无论如何,尽管异常和不设置标签的字段。我想知道里面发生了什么。
这是一个答案,部分解释了为什么它发生,所以当我得到它SetWindowText不工作的标签从不同的线程,但它确实为按钮工作。我说的对吗?
另外,我想知道这种行为是否持久。这取决于什么吗?在调试器吗?操作系统或。net版本?64位vs 32位?
提前感谢!
这是我在这里解释的行为:https://stackoverflow.com/a/37898886/869621
长话短说,有一个内部文本缓存激活的一些控件。活动时,在执行引发跨线程异常的行之前设置此缓存。因此,下次刷新UI时,即使抛出异常,控件文本也具有预期的值。
由于某些原因,标签没有启用此缓存。这就是为什么你只能设置按钮的文本,而不能设置标签的文本。
要知道这种行为是否持久,是和不是。是的,它将在当前版本的。net上持续工作。但是,不,这是一个实现细节,没有文档记录,所以当。net框架更新时,它可能会中断。不要依赖它,只使用UI线程来更新控件。