我有一个包含WPF表单的dll。这个DLL将由另一个WPF应用程序调用,不幸的是我无法触摸它。问题是我的WPF表单中没有Main方法来放置
[STAThread]
static void Main() {
//...
}
异常会在我的类的构造函数上抛出。在这种情况下,如何解决此STA问题。同样,这不是一个WPF应用程序,而是一个位于dll内部的WPF表单。
namespace VisualScannerTest
{
/// <summary>
/// Interaction logic for VisualScanner.xaml
/// </summary>
public partial class VisualScanner :Window,IPeripheral<VisualScanner.VisualScannerSettings>
{
private VisualScannerSettings _settings;
private readonly IEventManager _eventManager;
public VisualScanner(IEventManager eventManager):base()
{
InitializeComponent();
_eventManager = eventManager;
}
private void SubmitButton_Click(object sender, RoutedEventArgs e)
{
string input = InpuTextBox.Text;
InpuTextBox.Text = string.Empty;
if (!string.IsNullOrWhiteSpace(input))
{
_eventManager.GetEvent<PeripheralEvent>().Publish(new PeripheralEventData {RawData = input});
}
}
public void Initialize(VisualScannerSettings settings)
{
_settings = settings;
}
public IEnumerable<string> RegisterImpulses()
{
yield break;
}
public string Type
{
get { return GetType().FullName; }
}
public sealed class VisualScannerSettings:PeripheralSettings
{
public string Data { get; set; }
}
}
}
答案 0 :(得分:1)
我会建议您将dll转换为另一个拥有它自己的线程的WPF应用程序,然后您需要一种不同的方式与它进行通信 - 例如使用另一个dll两个应用程序引用或使用{{{{ 3}},例如TCP套接字。
或者,您可以尝试在dll
中公开需要在消费者的STA线程上调用的内容。所以你的应用程序可以调用它,例如:
CreateForm();
例如,。
虽然这可能不起作用 - 你需要设置一些东西来使WPF打勾,这不仅仅是使用STA线程的问题:
将SetSynchronizationContext设置为DispatcherSynchronizationContext
SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
创建System.Windows.Application()
使用Application.LoadComponent()`加载和添加任何XAML资源。
var resources = System.Windows.Application.LoadComponent(new Uri(&#34; /Styles.xaml",UriKind.Relative)); Resources.MergedDictionaries.Add(资源);
您需要以编程方式抽取Dispatcher
:
Dispatcher.CurrentDispatcher.PushFrame();
答案 1 :(得分:1)
我有同样的问题。您需要使用TaskScheduler。重要的是设置ApartmentState。
public static async Task Main()
{
var taskScheduler = new SingleThreadTaskScheduler(ApartmentState.STA);
var taskList = new List<Task>();
var updateTask = Task.Run(InstallHelper.CheckForUpdatesAsync);
updateTask.Wait();
taskList.Add(updateTask);
var tasks = await Task.Factory.ContinueWhenAll(taskList.ToArray(), result =>
Task.Factory.StartNew( ()=>MyAppSynchronMethodToRunIn_STAThread,
taskScheduler));
}