我应该调用或更改我的获取/设置方法吗";InvalidOperationException”;C#
本文关键字:quot InvalidOperationException 方法 设置 调用 我的 获取 我应该 | 更新日期: 2023-09-27 18:19:48
我得到一个InvalidOperationException消息,
控件控件名称从创建它的线程以外的线程访问。
"Control"是由一个不再做任何工作的线程创建的,我不知道如何调用该方法,或者是否应该创建一个包含tags_richtextbox值的局部变量。给出错误的类:
public class details_Panel
{
public string tags
{
get { return tags_richtextbox.Text; }
set { tags_richtextbox.Text = value; }
}
private RichTextBox tags_richtextbox = new RichTextBox() { DetectUrls = false, Dock = System.Windows.Forms.DockStyle.Fill, ReadOnly = true };
}
给出错误的函数:
detailsPanelSaveData.tags.AddRange(ent.detailspanel.tags.Split(','));
那么,我应该调用或添加一个与tags_richtextbox.Text具有相同值的私有变量吗?如果我应该调用,那么执行该操作并等待它完成的语法是什么?(我仍在学习线程并找出正确的调用语法)
编辑:DetailPanelSaveData.tags是List<string>
刚刚意识到我不太清楚
因此,为了Clarify,我试图在字符串列表中保存一个拆分的字符串。
"控制"是由一个不再做任何工作的线程创建的
如果没有一个好的、最小、完整的代码示例来可靠地再现问题,就不可能完全理解问题。然而,至少可以说,有一个线程创建了某个控件实例,但该线程"不再做任何工作"的想法有点奇怪。
控件对象必须只能在运行UI的线程中创建。在大多数程序中,只有一个这样的线程,而且应该只有一个。如果代码在另一个线程中运行,并且由于该线程中的某些操作,需要在某个点创建控件,则需要将执行转移到该UI线程以创建控件,以便在正确的线程中创建控件。
如果没有更好的代码示例,还不清楚还需要修复哪些。但可以肯定的是,您需要更改创建该控件的代码,以便在UI线程中创建控件。
在其他地方,例如,当您将文本转换为要添加到列表中的标记数组时,当您访问访问tags_richtextbox
对象的tags
属性时,您可能还需要将执行转移到UI线程。或者你不会。这一切都取决于代码执行的位置;如果它在UI线程中,那么一切都准备好了。否则,是…您需要将操作封装在某种跨线程调用中。
注意:您的问题中没有任何地方具体说明您正在使用.NET中的哪个GUI API。从代码和你在问题中的评论来看,我猜这就是Winforms。但WPF和Winrt(应用商店)也有同样的问题,因此上述建议同样适用于所有场景。当然,将执行转移到UI线程的确切技术因API而异。Winforms使用Control.Invoke()
,WPF使用Dispatcher.Invoke()
,Winrt使用Dispatcher.RunAsync()
。当我描述"跨线程调用"或需要"将执行转移到UI线程"时,我指的是这些方法(或者它们的异步等价物,在Winforms或WPF的情况下)。
注意:以上有一个例外,我甚至不愿意提及,因为我怀疑它是否适用于您的场景,即使适用,您应该做的第一件事就是修复代码,使其不适用。但为了完整起见,我不得不提到一个程序一次可以运行多个UI线程。这种情况很少见,应该避免,但也有可能发生。如果是这样,那么有可能在一个线程中创建一个控制对象,该线程与拥有其他控制对象的线程合法不同。现在,在这种情况下,您有责任确保任何给定的UI线程在其拥有的任何对象仍然存在的情况下继续运行,并且当对象被拥有它的线程之外的线程访问时,您仍然需要使用GUI API的机制来将执行转移到不同的线程,您可能最终得到一个由"不再执行任何工作"的UI线程创建的控制对象。