简体   繁体   English

并发修改Roslyn工作区? Visual Studio如何做到这一点?

[英]Concurrency of modifying a Roslyn workspace? How does Visual studio do it?

probably a stupid question, but: Is there any way to reliable apply changes to a Roslyn workspace concurrently? 可能是一个愚蠢的问题,但是:有没有办法可靠地将更改同时应用于Roslyn工作区? And if not, what is the best practice to ensure it's done in correct order? 如果没有,确保最佳顺序​​的最佳实践是什么?

Example: Say you have some solution loaded into a Workspace, and have a basic function that will add a new project to the solution: 示例:假设您已将一些解决方案加载到工作区中,并且具有将向该解决方案添加新项目的基本功能:

private Workspace _workspace;

// This is not thread-safe, right?
void AddProject()
{
  var project = _workspace.CurrentSolution.AddProject(/* ... */);
  _workspace.TryApplyChanges(project.Solution);
}

First question: Correct me if wrong, but I think AddProject would not be thread-safe, is that correct? 第一个问题:如果错了,请纠正我,但是我认为AddProject不会是线程安全的,对吗?

For example, lets say you want to add to new projects concurrently. 例如,假设您要同时添加到新项目中。 So you call AddProject() twice concurrently. 因此,您同时调用两次AddProject()。

My understanding is there is a race condition, and you might end up with both projects added (if one of the calls completes TryApplyChanges before the other call reaches _workspace.CurrentSolution), or only one of the projects added (if both calls have reached _worksapce.CurrentSolution before either has executed TryApplyChanges). 我的理解是存在竞争状况,您可能最终会添加两个项目(如果其中一个调用在另一个调用到达_workspace.CurrentSolution之前完成了TryApplyChanges),或者仅添加了一个项目(如果两个调用都已达到_worksapce) .CurrentSolution之前已执行TryApplyChanges)。

Second question: If my understanding is correct, then is there any best way to avoid these concurrency issues? 第二个问题:如果我的理解是正确的,那么有什么最佳方法来避免这些并发问题? I suppose the only real way would be to schedule/execute each modification sequentually, right? 我想唯一的真实方法是依次安排/执行每个修改,对吗?

How does Visual Studio, for example, do this.. Are modifications to the Workspace eg only done on the Dispatcher? 例如,Visual Studio是如何做到的。对工作区的修改是否仅在分派器上完成?

Thanks 谢谢

The underlying code is thread-safe, but your usage is not. 基础代码是线程安全的,但您的用法不是。

TryApplyChanges() will return false if the solution changed in the meantime. 如果同时更改解决方案,则TryApplyChanges()将返回false。 If that happens, you need to try the changes again (starting from the new CurrentSolution ). 如果发生这种情况,您需要再次尝试更改(从新的CurrentSolution )。

Basically, you need to write 基本上,你需要写

Solution changed;
do {
  changed = _workspace.CurrentSolution....();
} while (!_workspace.TryApplyChanges(changed);

This is called a compare-and-swap loop; 这称为比较交换循环; see my blog for more details. 有关更多详细信息,请参见我的博客

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Visual Studio中使用更改后的Roslyn - How to use an altered Roslyn in Visual Studio 如何在Visual Studio中引用工作区目录 - how do I reference a workspace directory in Visual Studio 如何从 Visual Studio 编辑器中检索文本以与 Roslyn SyntaxTree 一起使用? - How do I retrieve text from the Visual Studio editor for use with Roslyn SyntaxTree? Roslyn诊断+ Visual Studio着色 - Roslyn Diagnostic + Visual Studio Colorisation 如何在Visual Studio 2015中使用roslyn C#编译器? - How to use roslyn c# compiler with visual studio 2015? 如何在Visual Studio 2017中禁用Roslyn语言服务? - How to Disable Roslyn Language Services in Visual Studio 2017? Roslyn:如何在Visual Studio外部加载现有项目 - Roslyn: How to load an existing project outside of Visual Studio 如何在给定的Roslyn SyntaxNode上打开Visual Studio代码编辑器? - How to open Visual Studio code editor at given Roslyn SyntaxNode? 如何在Visual Studio 2008中使用C#为其他窗口创建工作区窗口? - How do I create a workspace window for other windows using c# in visual studio 2008? 如何在DiagnosticAnalyzer和CodeFixProvider中进入工作区? (罗斯林) - How to get to Workspace in DiagnosticAnalyzer and CodeFixProvider? (Roslyn)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM