我在开发 WPF 应用程序时遇到了一个问题。该应用程序基于棱镜。应用程序使用棱镜引导程序启动,在加载任何窗口之前,应用程序在不同的线程 (STA) 上打开一个模态对话框,然后加载一堆东西(服务等)。该对话框在此期间打开并允许通知用户应用程序启动过程的进度(使用事件聚合器传递更新)。加载完成后,引导程序关闭对话框并打开主应用程序窗口。 到现在为止还挺好... 然后在关闭应用程序时,同样的事情正在发生。关闭主窗口,打开一个对话框(再次在新的 STA 线程上),以允许通知。但是现在,当点击 ShowDialog 调用(发生在新的 STA 线程内)时,会引发异常:“不能使用属于与其父 Freezable 不同的线程的 DependencyObject”。经过长时间的调试,我发现异常的原因是窗口的背景,它是从应用程序级别的合并字典中获取的画笔/图像(在 wpf UI 线程上实例化)。如果在没有 ResouceDictionary 的情况下加载图像 - 一切顺利。
总结: 只有在使用 resourceDictionary 并且仅在第二次调用新的 STA 线程时才会观察到异常,该线程又会加载一个 DialogBox 并在调用 ShowDialog 时准确地引发异常 如果您只有一个对话框(例如在开机时且仅在关机过程中对话),则不会发生异常。
我的问题是:这是什么原因?在这种情况下,这个异常究竟意味着什么?(我知道一般来说,其他线程会有某种 UI 线程更新,但是我不明白为什么这只发生在拨号+线程的第二个实例上)。
谢谢 :)
我们正在将 WPF 应用程序移植到 .NET Core 3,预览版 5。一些 NUnit 测试需要在 STA 线程中运行。如何才能做到这一点?
[STAThread]、[RequiresSTA] 等属性都不起作用。这也不起作用:[程序集:RequiresThread(ApartmentState.STA)]
Appparent 命名空间似乎没有在 .NET Core 3 中公开。
有没有人做过这个?
我已经为C#控制台应用程序编写了代码.它将剪贴板值复制到文件,并且运行时没有任何错误.
现在我想在其他C#项目中使用它与其他代码.
我用 [STAThread]之后class{},但它给了我一个错误:
:: Attribute'STAThread'在此声明类型上无效.它仅对'方法'声明有效.
我能做什么?
这是由另一个问题引发的.
具体地讲,我有一个在过程COM类中,在所定义的CLSID注册表为具有ThreadingModel的Both.
我们的进程激活了这个对象CoCreateInstance(不是 CoCreateInstanceEx,如果这对于进程内DLL服务器来说很重要)
给Both定文档中列出的规则的线程模型和给定规则:
Threading model of server | Apartment server is run in
------------------------------------------------------
Both | Same apartment as client
Run Code Online (Sandbox Code Playgroud)
鉴于汉斯在另一个答案中所写的内容:
...当需要在不同的线程上进行客户端调用时,就会发生编组....当comClass元素中指定的ThreadingModel需要它时,可能会发生.换句话说,当COM对象在一个线程上创建但在另一个线程上调用时,服务器不是线程安全的.
我的初步结论是,这样的对象永远不需要对其接口的调用进行隐式编组,因为该对象将始终与其客户端位于同一个公寓中.
这是正确的,即使客户端进程作为STA运行?
我们正在用C#开发一个多线程游戏引擎,我们遇到了一个问题,我们需要STAThread属性(或者手动将我们的线程设置为STA)以启用拖放支持(如果没有STA,就不能设置AllowDrop).但是,当我们启用STA并且更新方法比draw方法花费的时间更长时(如下所示),窗口不再正常运行 - 当它在任务栏中单击时,它不会像您期望的那样最小化和最大化它.不同系统的确切行为是不同的,我猜这种竞争条件会起作用.
这是我们的测试代码:
[STAThread]
public static void Main()
{
Form form = new Form();
form.Show();
Barrier barrier = new Barrier(2);
Thread updateThread = new Thread(() => {
while (true)
{
barrier.SignalAndWait();
Thread.Sleep(30); //Update
barrier.SignalAndWait();
}
});
updateThread.Start();
while (true)
{
barrier.SignalAndWait();
Thread.Sleep(15); //Draw
barrier.SignalAndWait();
Application.DoEvents();
}
}
Run Code Online (Sandbox Code Playgroud) 与奇怪的行为......

大家好!
任何人都可以解释我,它怎么可能?
谢谢,亚历克斯.
我正在研究关于C#WPF程序的论文,但我遇到了一个我不明白的错误.
在我的MainWindow代码的某处,我开始一个新的线程,如下所示:
Thread searchServer = new Thread(new ThreadStart(doSearchServer));
searchServer.SetApartmentState(ApartmentState.STA);
searchServer.Start();
Run Code Online (Sandbox Code Playgroud)
doSearchServer方法执行以下操作:
private void doSearchServer()
{
bool connected = ServerConnection.authentication();
ServerConnection.getDeviceList();
gotDataFromServer = connected;
if (connected)
..
..
}
Run Code Online (Sandbox Code Playgroud)
ServerConnection类是静态的,因为我在其他Windows中也需要该类.
在ServerConnection.authentication()中,客户端(我的程序)尝试在我的服务器上进行身份验证.如果需要密码,我想打开一个新的PasswordWindow,如下所示:
public static bool authentication()
{
UdpClient client = new UdpClient();
IPEndPoint ip = new IPEndPoint(IPAddress.Broadcast, 55042);
IPEndPoint ipRec = new IPEndPoint(IPAddress.Any, 0);
byte[] bytes = Encoding.UTF8.GetBytes("authent|Username|Windows");
client.Send(bytes, bytes.Length, ip);
//Receive Answer
byte[] recBuffer = client.Receive(ref ipRec);
string recString = Encoding.UTF8.GetString(recBuffer);
if (recString.Equals("authent|password"))
{
//Send Passwort
Console.WriteLine("Password Required");
Dispatcher.CurrentDispatcher.Invoke(new Action(() => …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码片段:
let t1 = async { return process1() }
let t2 = async { return process2() }
let t3 = async { return windowsProcess() }
let execute =
[ t1; t2; t3 ]
|> Async.Parallel
|> Async.RunSynchronously
|> ignore
在windowsProcess需要STATHREAD的情况下该怎么办?这种结构有可能吗?
我正在使用来自后台线程的STA COM对象,其中一个COM对象的方法将阻塞,当我从处于STA线程模式的新线程调用它时,因为COM对象的模式是STA,并且UI线程似乎也被阻止了,我可以避免这种UI阻止吗?
当我尝试OpenFileDialog在WinForm中启动时,我最近在程序中遇到了与STA相关的错误.我已经做了一些阅读,在我将[STAThread]属性添加到主线程之前,我想知道它将如何影响我的程序执行.
我是COM的外国人,所以我读到的所有内容都不适合我.与我相关的一些观点是:
[STAThread]属性将应用程序定义为使用单线程单元模型.更具体地说,它将应用程序线程的状态更改为单线程. http://www.a2zdotnet.com/View.aspx?Id=93
当许多线程访问对象时,STA体系结构会施加显着的性能损失.每个线程对该对象的访问都是序列化的,因此每个线程必须排队等待轮到该对象.
http://www.codeproject.com/Articles/9190/Understanding-The-COM-Single-Threaded-Apartment-Pa
我了解线程安全的需要,但我还是不明白什么 STAThread一样.在我的程序(我从另一个开发人员继承)中,主线程启动了几个其他线程,其中一个初始化UI表单 - 我认为这是问题出现的地方.随着[STAThread]加入会发生什么新的线程?这是否会影响非Windows对象的多线程通信?
当我尝试OpenFileDialog在其中一个表单中打开时发生错误.我使用VS设计器将对话框添加到表单中:它不起作用.然后我尝试在全局文件中创建一个对话框,该文件由主线程运行并从我的表单中调用该实例.它没有效果.
sta ×10
c# ×7
.net ×3
com ×3
winforms ×2
wpf ×2
.net-core ×1
apartments ×1
c++ ×1
console ×1
dispatcher ×1
f# ×1
marshalling ×1
nunit ×1
prism ×1