我是WPF的新手,在我读过的每个教程中,他们要么将一个[System.STAThread]属性应用于他们的Main方法,要么告诉读者这样做.
这个属性真的"需要"吗?如果是这样,为什么?
我创建了一个将调用某些COM组件的Windows服务,因此我将[STAThread]标记为Main函数.但是,当计时器触发时,它会报告MTA并且COM调用失败.我怎样才能解决这个问题?
using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;
using System.Timers;
namespace MyMonitorService
{
public class MyMonitor : ServiceBase
{
#region Members
private System.Timers.Timer timer = new System.Timers.Timer();
#endregion
#region Construction
public MyMonitor ()
{
this.timer.Interval = 10000; // set for 10 seconds
this.timer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed);
}
#endregion
private void timer_Elapsed (object sender, ElapsedEventArgs e)
{
EventLog.WriteEntry("MyMonitor", String.Format("Thread Model: {0}", Thread.CurrentThread.GetApartmentState().ToString()), EventLogEntryType.Information);
}
#region Service Start/Stop
[STAThread]
public static void Main ()
{
ServiceBase.Run(new MyMonitor());
}
protected override void …Run Code Online (Sandbox Code Playgroud) 我想将Keith Hill的Get-Clipboard和Set-Clipboard的C#实现转换为纯PowerShell作为.PSM1文件.
有没有办法在PowerShell中启动STA线程,就像他在使用剪贴板时在Cmdlet中那样?
虽然有很多关于COM和STA/MTA的问题(例如这里),但大多数人都在讨论具有UI的应用程序.但是,我有以下设置:
[MTAThread]属性).几个问题:
ConcurrentQueue.我有一个COM服务器(C++/STA(基于MFC的应用程序))和一个COM客户端(C#/ MTA).COM服务器必须位于STA中,因为它是一个MFC应用程序(在这个问题上我别无选择).客户端向服务器发出调用,服务器向客户端发出回调.这就是错误发生的地方(RPC_E_CANTCALLOUT_ININPUTSYNCCALL).我猜测服务器是否是MTA,这个问题永远不会出现,但遗憾的是,MFC的文档明确否认将公寓初始化为MTA.
关于如何解决这个问题的任何想法?
我一直在想让服务器对象(我通过运行对象表公开的对象)住在自己的公寓(MTA)中.这是一个好主意,还是先尝试一些简单的东西?
UPDATE
服务器对象只是指向应用程序中某些功能的精简界面.大多数情况下,它只是读取和写入内存位置,但有些情况下它会向应用程序中的各个窗口生成窗口消息.服务器对象本身不是整个应用程序.
首先,我已经阅读了网站上类似问题的几个答案,但说实话,我发现它们有点令人困惑(由于我缺乏经验而不是答案!).我正在使用FileSystemWatcher()类来监视正在创建/更改的文件的文件夹.一旦事件发生,我就想在项目中加载另一个表单.而不是加载表单我在新表单上的构造函数尝试执行时得到错误.我只使用一个线程 - 我不是试图在不同的线程下加载表单.我的代码如下
//MainWindow
public static void FolderWatcher()
{
FileSystemWatcher fsWatcher = new FileSystemWatcher();
fsWatcher.Path = "C:\\dump";
fsWatcher.Filter = "*";
fsWatcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
fsWatcher.Created += new FileSystemEventHandler(OnChanged);
fsWatcher.EnableRaisingEvents = true;
}
public static void OnChanged(object source, FileSystemEventArgs e)
{
var imagePreview = new ImagePreview();
imagePreview.Show();
}
//SecondForm
public partial class ImagePreview : Window
{
public ImagePreview()
{
InitializeComponent(); //error occurs here
}
}
Run Code Online (Sandbox Code Playgroud)
希望你能提前帮助,非常感谢.
在Watin的源代码中,有这段代码:
public void NavigateToNoWait(Uri url)
{
var thread = new Thread(GoToNoWaitInternal);
thread.SetApartmentState(ApartmentState.STA);
thread.Start(url);
thread.Join(500);
}
[STAThread]
private void GoToNoWaitInternal(object uriIn)
{
var uri = (Uri)uriIn;
NavigateTo(uri);
}
Run Code Online (Sandbox Code Playgroud)
由于创建的线程设置了其单元状态,为什么该[STAThread]属性被添加到方法中?我对特定的代码段不感兴趣,但我想知道是否STAThread需要属性.
笔记:
GoToNoWaitInternal不在别处使用.在过去的几个月里,我一直在涉足Powershell(2.0),并且很乐意使用它来实现工作中的一些流程的现代化和标准化 - 主要是基于DOS的流程.由于工作的性质,可能会同时执行大约100次相同的脚本执行.
首先 - Powershell以这种方式"安全"使用吗?我已经看到-STA作为执行选项 - 是在同时执行大量相同脚本时使用Powershell的首选方法,还是仅在绝对必要时才使用的东西?在我的搜索中,我还没有真正想出"我什么时候应该使用公寓状态?"的答案.我相信大多数(如果不是全部)我打算做的脚本都不会被线程化.
在此先感谢任何能够了解Powershell公寓状态的人!
我有一个 Windows 窗体应用程序。
现在我想使用一种async方法。
从 C# 7.1 开始,我可以使用一种async Main方法:https :
//docs.microsoft.com/en-us/dotnet/csharp/whats-new/csharp-7-1
但是,现在我的STAThread属性被忽略,我的应用程序在 MTA 中运行。这是设计使然还是我可以强制我的应用程序再次在 STA 模式下运行?
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
private static async Task Main(string[] args)
{
// returns MTA
Console.WriteLine("{0}", Thread.CurrentThread.ApartmentState);
}
Run Code Online (Sandbox Code Playgroud) 我需要STA在ASP.NET应用程序中使用多个线程来使用某些COM组件.
我在每个进程内的某处读取,只能STA存在一个线程.我编写了一个示例项目并创建了许多线程并将其公寓状态设置为,STA并且它们可以COM毫无例外地处理对象.
是否可以STA在进程中包含许多线程?
sta ×10
c# ×6
mta ×3
com ×2
powershell ×2
wpf ×2
.net ×1
async-await ×1
com-interop ×1
visual-c++ ×1
watin ×1