首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PInvoke在带ui/非ui线程差异的WPF中的应用

PInvoke在带ui/非ui线程差异的WPF中的应用
EN

Stack Overflow用户
提问于 2013-02-05 16:44:26
回答 1查看 980关注 0票数 0

我从WPF应用程序中的c++代码访问c# dll库。从ui线程访问dll时没有问题。但是,在运行c++ dll的代码时,我需要UI具有响应性。所以我试着从另一个线程访问它。但是,当我第一次尝试在非ui线程中调用相同的函数(从ui线程调用的函数)时,函数会返回,但返回值表示函数中存在内部错误。但是,当我从一个非ui线程再运行一两次时,它成功地返回了一个非错误值。我没有dll的源代码,所以我不知道里面发生了什么。

c++函数

代码语言:javascript
复制
UINT32 myfunc1()

在C#中

代码语言:javascript
复制
[DllImport("mydll.dll")]
public static extern uint myfunc1();

如何到达ui线程中的代码

代码语言:javascript
复制
uint errorCode = myfunc1(); // returns 0 means no error occured

如何在非ui线程中访问代码

代码语言:javascript
复制
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += (s, args) => { args.Result = myfunc1(); };
// 1st call args.Result is 10 means internal error ocurred
// 2nd call args.Result is sometimes 0 and sometimes 10
// 3rd or later calls args.Result is 0 means no error occured
worker.RunWorkerCompleted += doSth();
worker.RunWorkerAsync();
EN

回答 1

Stack Overflow用户

发布于 2013-02-05 17:17:13

它可能与线程上使用的公寓模型有关。

您的UI线程将使用STA (单线程单元) model...it依赖消息循环进行同步/序列化访问。

您的BackgroundWorker将使用MTA (多线程公寓)模型。

该DLL库中可能有一些代码依赖于在UI/STA线程中运行,以实现适当的同步,例如,一些COM调用。它有时起作用,有时不起作用,原因很可能是种族condition...due缺乏同步。

可以指定线程是STA one....but,而不是在BackgroundWorker线程上,因为它们是由ThreadPool创建和管理的,并且总是被设置为使用MTA单元模型、被重用,etc....and线程必须在成为不能更改的started...after之前设置它的单元状态。

因此,相反,创建一个新的Thread,将其公寓设置为STA,并提供消息处理。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14712527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档