- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个专有的 COM 库,它返回一个整数数组(当然是它们自己专有的格式)。当我从主 UI 线程访问这个数组时,一切都很好并且运行很快。当我从另一个线程访问它时,访问速度很慢。下面是一些示例代码。
private void test() {
ProprietaryLib.Integers ints = ProprietaryLib.GetInts();
int x;
for(int i = 0; i < 500; i++)
for(int j = 0; j < ints.Count; j++)
x = ints[j];
}
private void button1_Click(object sender, EventArgs e) {
test(); // Very little time
new System.Threading.Thread(() => test()).Start(); // Lots of time
}
为什么会这样?我有什么办法可以加快速度吗?如果我使用多处理而不是多线程,那么我是否有希望获得良好的性能? (虽然,听起来要复杂得多。)
更新:
我对下面的答案很满意,但想在这里添加一些数据以供引用(我自己的和其他人的)。
如上所示在新线程中创建和访问对象每次访问大约需要 12ns。据推测,该对象实际上是在主线程上创建的,速度慢是因为从那里编码数据。
如果您在主线程上显式创建数据,但在标记为单线程单元的新线程中访问它,则访问时间会更慢,每次访问需要 15 纳秒。我想 .NET 一定有一些额外的开销来保持公寓的美观,尽管我担心我不知道这些开销是多少。虽然只有 2-3 ns 的差异,但它不会太大。
如果您在标记为 STA 的新线程上创建和访问对象,则每次访问的时间会减少 0.2ns。但是这个新线程真的安全吗?这是我想的另一个问题的问题。
最佳答案
COM 对象具有线程亲和性,它们可以告诉 COM 它们不是线程安全的。使用注册表中的键“ThreadingModel”键。绝大多数人这样做,要么通过指定“公寓”,要么只是省略 key 。它在 .NET 中不太明确,它使用 MSDN 告诉您类不是线程安全的,并且不会以其他方式提醒您忘记阅读这篇文章。绝大多数 .NET 类都不是线程安全的,与 COM 组件类没有区别。与 .NET 不同,COM 确保以线程安全的方式调用它们。通过自动编码(marshal)对创建对象的线程的调用。
也就是说,没有并发,很慢。
取得成功的唯一方法是创建您自己的 Thread 并调用其 SetApartmentState() 方法以切换到 STA,这是非线程安全的 COM 对象的幸福家园。您还必须在该线程上创建 COM 对象。而且您可能必须泵送消息循环以使其保持事件状态,这是 STA 的要求。永远不要阻塞线程。这些是使它成为非线程安全类的幸福归宿的原因,如果所有调用都在一个线程上进行,那么就不会出错。您可以找到此类线程的示例实现 in this answer .
或者换句话说,当线程与非线程安全的对象一起使用时,天下没有免费的午餐。 .NET 让您在需要时忘记使用 lock 来开枪,而 COM 使它自动进行。以这种方式单腿跳动的程序员要少得多,但效率不高。
关于c# - 在 C# 中从主线程以外的线程访问 COM 对象速度慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10643652/
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
PowerShell Web Access 允许您通过 Web 浏览器运行 PowerShell cmdlet。它显示了一个基于 Web 的控制台窗口。 有没有办法运行 cmdlet 而无需在控制台窗
我尝试在无需用户登录的情况下访问 Sharepoint 文件。 我可以通过以下任一方式获取访问 token 方法一: var client = new RestClient("https://logi
我目前正在尝试通过 Chrome 扩展程序访问 Google 服务。我的理解是,对于 JS 应用程序,Google 首选的身份验证机制是 OAuth。我的应用目前已成功通过 OAuth 向服务进行身份
假设我有纯抽象类 IHandler 和派生自它的类: class IHandler { public: virtual int process_input(char input) = 0; };
我有一个带有 ThymeLeaf 和 Dojo 的 Spring 应用程序,这给我带来了问题。当我从我的 HTML 文件中引用 CSS 文件时,它们在 Firebug 中显示为中止。但是,当我通过在地
这个问题已经有答案了: JavaScript property access: dot notation vs. brackets? (17 个回答) 已关闭 6 年前。 为什么这不起作用? func
我想将所有流量重定向到 https,只有 robot.txt 应该可以通过 http 访问。 是否可以为 robot.txt 文件创建异常(exception)? 我的 .htaccess 文件: R
我遇到了 LinkedIn OAuth2: "Unable to verify access token" 中描述的相同问题;但是,那里描述的解决方案并不能解决我的问题。 我能够成功请求访问 toke
问题 我有一个暴露给 *:8080 的 Docker 服务容器. 我无法通过 localhost:8080 访问容器. Chrome /curl无限期挂断。 但是如果我使用任何其他本地IP,我就可以访
我正在使用 Google 的 Oauth 2.0 来获取用户的 access_token,但我不知道如何将它与 imaplib 一起使用来访问收件箱。 最佳答案 下面是带有 oauth 2.0 的 I
我正在做 docker 入门指南:https://docs.docker.com/get-started/part3/#recap-and-cheat-sheet-optional docker-co
我正在尝试使用静态 IP 在 AKS 上创建一个 Web 应用程序,自然找到了一个带有 Nginx ingress controller in Azure's documentation 的解决方案。
这是我在名为 foo.js 的文件中的代码。 console.log('module.exports:', module.exports) console.log('module.id:', modu
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用 MGTwitterEngine"将 twitter 集成到我的应用程序中。它在 iOS 4.2 上运行良好。当我尝试从任何 iOS 5 设备访问 twitter 时,我遇到了身份验证 to
我试图理解访问键。我读过https://docs.aws.amazon.com/general/latest/gr/aws-sec-cred-types.html#access-keys-and-se
我正在使用以下 API 列出我的 Facebook 好友。 https://graph.facebook.com/me/friends?access_token= ??? 我想知道访问 token 过
401 Unauthorized - Show headers - { "error": { "errors": [ { "domain": "global", "reas
我已经将我的 django 应用程序部署到 heroku 并使用 Amazon s3 存储桶存储静态文件,我发现从 s3 存储桶到 heroku 获取数据没有问题。但是,当我测试查看内容存储位置时,除
我是一名优秀的程序员,十分优秀!