C# Akka.net在STA中的演员

C# Akka.net在STA中的演员,c#,com,ms-word,sta,akka.net,C#,Com,Ms Word,Sta,Akka.net,我需要将数千个不同格式的ms office文档转换为一种通用格式。为了加快速度,我将使用akka.net对其进行并行化。WordSaveAsActor应该: 磨合单螺纹装置 保存Word应用程序实例 在此实例上进行COM调用,例如使用从多个并行线程接收的消息的路径进行SaveAs(..) 在发生任何故障时重新启动自身 甚至可以在STA中运行akka.net actor吗?如果我以这种方式使用akka.net,会有什么问题吗?简短的回答是“是的,你可以用akka.net这样做” 正如汉斯在评论

我需要将数千个不同格式的ms office文档转换为一种通用格式。为了加快速度,我将使用akka.net对其进行并行化。WordSaveAsActor应该:

  • 磨合单螺纹装置
  • 保存Word应用程序实例
  • 在此实例上进行COM调用,例如使用从多个并行线程接收的消息的路径进行SaveAs(..)
  • 在发生任何故障时重新启动自身
甚至可以在STA中运行akka.net actor吗?如果我以这种方式使用akka.net,会有什么问题吗?

简短的回答是“是的,你可以用akka.net这样做”

正如汉斯在评论中指出的那样:


Word不太关心你的图书馆。它的互操作接口是单线程的,您从工作线程发出的任何调用都会自动封送到拥有应用程序对象的线程

您可以使用Akka.NET中的dispatchers对参与者的并发需求进行某种控制—您可以

在你的情况下,我建议你这样做:

  • 在STA线程上创建您的
    WordSaveAsActor
    ,并将其配置为使用Akka.NET中的
    CurrentSynchronizationContextDispatcher
    ,您可以通过以下配置执行此操作:
  • 
    var wordActor=MyActorSystem.ActorOf(Props.Create(()=>newwordsaveasactor(…).WithDispatcher(“akka.actor.synchronized dispatcher”))
    

    此参与者处理的所有消息都将在STA线程上自动完成。我们在其他STA环境中使用此技术,例如Windows窗体UI,它大大简化了一切

  • 在使用默认dispatcher(CLR线程池)的其他参与者上执行不需要Word COM组件的所有其他工作。这可能包括任何文件复制、打开、移动等。。当您需要向word发送数据或从word接收数据时,您可以让这些参与者将消息传递给您的
    WordSaveAsActor

  • 正如Hans指出的,除非您并行运行Word的多个实例,否则利用其COM API一次不能执行多个操作。因此,为了利用Akka.NET的并行性,您需要找到一种方法,使用多个参与者来并行化操作中不需要Word的部分。

    Word不太关心您的库。它的互操作接口是单线程的,您从工作线程发出的任何调用都会自动封送到拥有应用程序对象的线程。它不会更快,它会更慢。您最多可以在不同的worker中处理不同的文档,每个worker都拥有自己的应用程序。这就停止了快速扩展,Word是一个非常繁重的过程。你不是说10000个Word应用程序实例吗?如果我只发送路径,为什么速度会变慢?即使使用async/await代替BackgroundWorker并寻找更好的解决方案,我也会产生奇怪的效果和崩溃。非常感谢您的详细解释!我正在关注你在github上的积极进展。现在只完成了第1单元:)将练习移植到F#上,这使练习更加简单!我将运行一两个文字演员,这仍然是一个瓶颈。我认为将字符串传递给参与者的开销要比在后台使用文件系统访问的繁重的word操作便宜得多,不是吗?将字符串传递给参与者的开销非常便宜——我们的乒乓球基准测试可以在8核开发机器上每秒发送6000万条消息。