Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用顶级Program.cs处理C#9中的{STAThread]_C#_C# 9.0 - Fatal编程技术网

如何使用顶级Program.cs处理C#9中的{STAThread]

如何使用顶级Program.cs处理C#9中的{STAThread],c#,c#-9.0,C#,C# 9.0,我刚刚进入C#9,正在尝试实现顶级语句,特别是在无处不在的Program.cs中。我在一个案例中成功地实现了这一点,但在第二个案例中,应用程序在OpenFileDialog()中获得了ThreadStateException 我替换了生成的Program.cs using System; using System.Windows.Forms; namespace MapLines { static class Program { /// <summary>

我刚刚进入C#9,正在尝试实现顶级语句,特别是在无处不在的Program.cs中。我在一个案例中成功地实现了这一点,但在第二个案例中,应用程序在OpenFileDialog()中获得了ThreadStateException

我替换了生成的Program.cs

using System;
using System.Windows.Forms;

namespace MapLines {
    static class Program {
        /// <summary>
        ///  The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() {
            Application.SetHighDpiMode(HighDpiMode.SystemAware);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}
这是OpenFileDialog中的异常

System.Threading.ThreadStateException
  HResult=0x80131520
  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
  StackTrace:
   at System.Windows.Forms.FileDialog.RunDialog(IntPtr hWndOwner)
   at System.Windows.Forms.CommonDialog.ShowDialog(IWin32Window owner)
   at System.Windows.Forms.CommonDialog.ShowDialog()
   at MapLines.MainForm.OnOpenImageClick(Object sender, EventArgs e) in C:\Users\evans\Documents\Visual Studio 2019\Projects\Map Lines\Map Lines\MainForm.cs:line 664
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, WM msg, IntPtr wparam, IntPtr lparam)
回到原始的Program.cs,它有[STAThread],修复了它

我发现的关于C#9新功能的文章中没有一篇提到这一点。这似乎很重要,因为肯定有很多应用程序使用OpenFileDialog()和其他可能的功能。据我所知,Winforms需要单线程单元(STA)线程化。当需要STA线程化时,有没有办法使用顶级语句?

使用System.threading;
使用System.Windows.Forms;
使用地图线;
变量线程=新线程(()=>
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
运行(新的MainForm());
});
SetApartmentState(ApartmentState.STA);
thread.Start();

有可能,这是一个运行良好的最小示例:

使用系统线程;
使用System.Windows.Forms;
//这很不幸,但我们必须先把它设为未知。
Thread.CurrentThread.SetApartmentState(ApartmentState.Unknown);
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(默认值:false);
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
Application.Run(新表单());

来源:这张来自dotnet/winforms Github的票证:

不,需要传统风格。不确定为什么现在会有反对票。这似乎是合理的,而且似乎有效。让我试一下,看看是否有什么问题(或者是否有人有更好的想法),我会将其标记为解决方案。使用此解决方案还是使用模板生成的原始版本可能会有争议,但它回答了我的问题。我思考了很长时间,目前还没有找到更好的解决方案(可能C#9.1+中出现了一些解决此问题的方法)。另一个可能的改进是NuGet包,它将此代码简化为调用Main.Run(()=>{your code})。我一直在使用此方法,它似乎很有效。从实际角度看,我没有看到任何不同。我对此进行了改进。是的,从“哇,看,C#9真是太棒了,不需要所有的锅炉板就可以开始了!”这让维护人员有点失望。对于任何不需要
STAThread
的东西来说,它都是很棒的,但除此之外,这并不美妙。我会使用
thread.Join()
after
thread.Start()
等待线程完成执行。
System.Threading.ThreadStateException
  HResult=0x80131520
  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
  StackTrace:
   at System.Windows.Forms.FileDialog.RunDialog(IntPtr hWndOwner)
   at System.Windows.Forms.CommonDialog.ShowDialog(IWin32Window owner)
   at System.Windows.Forms.CommonDialog.ShowDialog()
   at MapLines.MainForm.OnOpenImageClick(Object sender, EventArgs e) in C:\Users\evans\Documents\Visual Studio 2019\Projects\Map Lines\Map Lines\MainForm.cs:line 664
   at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e)
   at System.Windows.Forms.ToolStripMenuItem.OnClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e)
   at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e)
   at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.ToolStripDropDown.OnMouseUp(MouseEventArgs mea)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
   at System.Windows.Forms.ToolStrip.WndProc(Message& m)
   at System.Windows.Forms.ToolStripDropDown.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, WM msg, IntPtr wparam, IntPtr lparam)