[英]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.