所以我正在使用 windowsAPICodepack 中的 CommonOpenFileDialog。在我正在编写的应用程序的早期版本中,CommonOpenFileDialog 没有任何问题。在针对更高版本的 .Net Framework 的当前版本中,即使通过主窗体中的工具条菜单项单击事件从主 UI 线程调用对话框,我也会得到跨线程操作无效异常。之前它曾经以类似的方式从主窗体的按钮单击处理程序中调用。
显式调用在同一表单上显示 CommonOpenFileDialog 的相同代码可以解决此问题,但通常的对话框行为会以这种方式丢失。
这有效,但没有 this.Invoke 则无效。
private void loadWorkspaceToolStripMenuItem_Click(object sender, EventArgs e)
{
bool wait = true;
this.Invoke((MethodInvoker)delegate ()
{
string startPath = LastUsedPath;
if (FileFolderTools.ShowFolderChooser(ref startPath))
{
workspace.LoadWorkspace(startPath);
LastUsedPath = startPath;
}
wait = false;
});
while(wait){}
}
此外,虽然 while(wait) 存在,但 UI 仍然是响应式的,而当按下按钮进行阻塞调用时,通常情况并非如此。不知道这里发生了什么......
编辑:底部更广泛的堆栈跟踪。
编辑 - 这是 ShowfolderChooser 所做的(正常时返回 true,取消时返回 false):
public static bool ShowFolderChooser(ref string path){
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = path;
dialog.IsFolderPicker = true;
CommonFileDialogResult res = dialog.ShowDialog();
if (res == CommonFileDialogResult.Ok)
{
path = dialog.FileName; //set new path on OK
return true;
}
return false;
}
完全例外:
This exception was originally thrown at this call stack:
[External Code]
DataManagement.DataManagementCore.Helpers.FileFolderTools.ShowFolderChooser(ref string) in FileFolderTools.cs
Camera._Camera.btn_exportAll_Click(object, System.EventArgs) in Camera.cs
[External Code]
Camera.Program.Main() in Program.cs
可是等等...!还有更多...
所以我尝试将该代码放在一个单独的应用程序中,并且它可以完美地工作。所以我想这与我的应用程序有关。我看到的一个很大不同是我的堆栈框架上loadWorkspaceToolStripMenuItem_Click
有一个堆栈条目user32.dll![Frames...
知道那个来自哪里吗?估计跟那个有关系...
EDIT2更广泛的堆栈跟踪:
at System.Windows.Forms.Control.get_Handle()
at Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialog.ApplyNativeSettings(IFileDialog dialog)
at Microsoft.WindowsAPICodePack.Dialogs.CommonFileDialog.ShowDialog()
at Camera._Camera.btn_exportAll_Click(Object sender, EventArgs e) in D:\XXXXXXXXXXXXXX\TestProjects\DataManagementTestProject\Camera\Mainscreen\Camera.cs:line 661
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at DataManagementTestProject.Program.Main() in D:\XXXXXXXXXXXXXX\TestProjects\DataManagementTestProject\Program.cs:line 20
从这个堆栈跟踪中,我可以确认调用是在 UI 的主线程上完成的,因为它应该是由 MessageLoop 调用的。似乎 getHandle 有问题在某处出错。但这是在 API 包中它应该可以工作......