C#-SaveFileDialog:InvalidOperationException由于在多线程应用程序中的“所有者”参数
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了C#-SaveFileDialog:InvalidOperationException由于在多线程应用程序中的“所有者”参数,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3169字,纯文字阅读大概需要5分钟。
内容图文
![C#-SaveFileDialog:InvalidOperationException由于在多线程应用程序中的“所有者”参数](/upload/InfoBanner/zyjiaocheng/653/ea2845d567f64063a05ebcbdcd4d8d88.jpg)
很长的帖子很抱歉,但是我试图非常详细地解释这个问题,以免引起混淆.最后一句包含实际问题.
我正在用C#/.NET编写多线程应用程序.
该应用程序包含一个主窗口,该窗口可可视化来自压力传感器的数据.传感器数据在自己的线程中获取.
数据也记录在类ListView的实例中:
可以通过“保存”按钮将记录的数据保存到磁盘上的文件(应打开.NET类SaveFileDialog的实例).
此SaveFileDialog也在自己的线程中运行.
现在调用方法SaveFileDialog.ShowDialog()时出现问题:
System.InvalidOperationException was unhandled
Message=”Cross-thread operation not valid: Control ‘tlpMain’ accessed from a thread other than the thread it was created on.”
Source=”System.Windows.Forms”
出现问题是因为SaveFileDialog的所有者(主窗口)在另一个线程中运行.
这是代码,它为SaveFileDialog()创建线程:
private void bSave_Click(object sender, EventArgs e)
{
Thread saveFileDialog = new Thread(OpenSaveFileDialog);
saveFileDialog.SetApartmentState(ApartmentState.STA);
saveFileDialog.Start();
}
方法OpenSaveFileDialog()的代码:
private void OpenSaveFileDialog()
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Text Files (*.txt)|*.txt|CSV (*.csv)|*.csv|All Files (*.*)|*.*";
saveFileDialog.FilterIndex = 0;
/* Call "ShowDialog" with an owner ("this.Parent") to achieve, so that
* the parent window is blocked and "unclickable".
*
* Danger of an "InvalidOperationException" because "this.Parent" control
* is running (was created) in another thread.
* But "this.Parent" should not be modified by this method call.
*/
DialogResult pressedButton = saveFileDialog.ShowDialog(this.Parent);
...
仅当使用Visual Studio的调试器运行应用程序时,才会引发/显示InvalidOperationException.到目前为止,“正常”运行应用程序没有问题.
但是我想避免这个问题.
我试图建立一个包装方法(SaveFileDialog):
private void OpenSaveFileDialog()
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
...
SaveFileDialog(saveFileDialog, this.Parent);
}
包装方法:
private void SaveFileDialog(SaveFileDialog saveFileDialog, Control owner)
{
if (owner.InvokeRequired)
BeginInvoke(new dSaveFileDialog(SaveFileDialog), new object[] { saveFileDialog, owner });
else
{
DialogResult pressedButton = saveFileDialog.ShowDialog(owner);
...
尽管Main()方法标记为[STAThreadAttribute],但这会导致TargetInvocationException:
InnerException: System.Threading.ThreadStateException
Message=”Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it. This exception is only raised if a debugger is attached to the process.”
Source=”System.Windows.Forms”
是否有人知道如何以某种方式打开SaveFileDialog,以便在没有(线程)麻烦的情况下阻止主窗口(“不可点击”)?
谢谢.
解决方法:
您在调试过程中遇到的跨线程异常为Managed Debugging Assistant.它们通常在调试器外部不活动.这就解释了为什么在Visual Studio外部运行应用程序时看不到.
似乎您已经发现自己无法对除主UI线程以外的其他线程的UI元素执行任何操作.您使用ISynchronizeInvoke方法(即Invoke或BeginInvoke)将操作的执行编组到UI线程上,以便可以安全地访问UI元素.
我仍然看到您的代码有问题.在运行于工作线程上的OpenSaveFileDialog方法中,您正在调用SaveFileDiaglog的构造函数,它当然是UI元素.您就是无法做到这一点.值得重复.您不能从辅助线程对窗体或控件执行任何操作.这包括调用构造函数.
内容总结
以上是互联网集市为您收集整理的C#-SaveFileDialog:InvalidOperationException由于在多线程应用程序中的“所有者”参数全部内容,希望文章能够帮你解决C#-SaveFileDialog:InvalidOperationException由于在多线程应用程序中的“所有者”参数所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。