使用WPF(需要STAThread)与无法使用STAThread的API工作

4
我正在编写一个WPF应用程序,它具有对API的可选依赖项,并且该API有一个简单的要求; 必须在没有STA线程属性的线程上进行初始化/使用。 当然,WPF需要STA,因此这一切都很容易。
在这种情况下,无论如何都需要WPF。 只有当用户选择在应用程序中启用此功能时才需要第三方API。 这意味着WPF应用程序已经在调用其他API时运行。
如果您没有使用[STAThread]装饰您的主方法,则它自动成为MTA线程吗? 在这种情况下,这是否意味着我可以创建一个新的MTA线程并在其上使用其他API?
如果这样可以,那么我想这个API的任何事件都可以使用Dispatcher与WPF应用程序通信(用于引发需要在UI中显示的事件等)。 但是,我的WPF应用程序是否有一种简单的方法来“调用”MTA线程上的功能以进行API调用?
在MTA中,我想每个线程都应该能够处理状态,但我想我的STA线程(WPF应用程序)不能只是“插手”MTA线程并执行API调用?
这里存在很多混淆的可能性,我希望能获得一些关于如何设计这样的东西的建议!
谢谢!
[编辑7月8日]
好了,我在上面混淆了一些概念。线程模型当然是为一个进程设置的,而不是为每个线程设置的,并且这个第三方API不能与STA进程一起使用。
目前,我唯一看到的解决方法是编写一个与该API通信的服务,然后使用命名管道与该服务通信。这一点都不简单,是一种丑陋的解决方法,但是第三方API不在我的控制之下。这就是人生。 :|
3个回答

6

外部API是GUI API吗?还是只是一些功能等等?如果是后者,那么您可以生成第二个线程(可能使用生产者/消费者队列)来执行多线程单元(MTA):

    Thread thread = new Thread(DoSomeStuff);
    thread.SetApartmentState(ApartmentState.MTA);
    thread.Name = "3rd aprty API spooler";
    thread.Start();

谢谢Marc - 我会尝试这个。外部API是一个电话系统,其中功能/事件需要一些时间(不是几秒钟,但是可以察觉)来执行,因此这看起来是一个好计划。 - Rune Jacobsen

3
您需要启动一个新线程来调用需要MTA线程的代码。 您可以尝试像下面这样轻松地在MTA线程上调用它。这将在MTA线程执行时阻塞主线程。这个方法的效率取决于您的API使用情况,因为每次调用都会启动一个新线程。
public delegate void MtaMethod();

public class MtaHelper
{

    public static void RunMta(MtaMethod method)
    {

        ManualResetEvent evnt = new ManualResetEvent(false);

        Thread thread = new Thread(delegate()
        {
            method();
            evnt.Set();
        });

        thread.SetApartmentState(ApartmentState.MTA);
        thread.Start();
        evnt.WaitOne();
    }

}

然后,您应该能够调用您的API,如下所示:
MtaHelper.RuntMta( () => OtherAPIMethod() );

嗨,感谢您的建议。我对此唯一的问题是阻塞,因为另一个API属于需要一些时间才能完成的类型。不过我还是会尝试一下这个方法的! - Rune Jacobsen

2
我在WPF中利用了DispatcherObject。
我创建了一个DispatcherObject的子类,然后使用MTA线程创建一个实例。这样,我就可以使用mySubclass.Invoke(...)或mySubclass.BeginInvoke(...),执行的代码将在我的MTA线程上运行。
你可以在这里看到一个例子:

http://wpfmediakit.codeplex.com/SourceControl/changeset/view/24019#283908

特别注意CreateDvdPlayer静态方法,并查看BaseClasses.cs中的基类。

Morill后来更改了解决方案,使用自己的消息泵创建了自定义的WorkDispatcher,请参见https://github.com/Sascha-L/WPF-MediaKit/tree/master/Source/Threading。 - xmedeko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接