[英]Concurrency of modifying a Roslyn workspace? How does Visual studio do it?
可能是一个愚蠢的问题,但是:有没有办法可靠地将更改同时应用于Roslyn工作区? 如果没有,确保最佳顺序的最佳实践是什么?
示例:假设您已将一些解决方案加载到工作区中,并且具有将向该解决方案添加新项目的基本功能:
private Workspace _workspace;
// This is not thread-safe, right?
void AddProject()
{
var project = _workspace.CurrentSolution.AddProject(/* ... */);
_workspace.TryApplyChanges(project.Solution);
}
第一个问题:如果错了,请纠正我,但是我认为AddProject不会是线程安全的,对吗?
例如,假设您要同时添加到新项目中。 因此,您同时调用两次AddProject()。
我的理解是存在竞争状况,您可能最终会添加两个项目(如果其中一个调用在另一个调用到达_workspace.CurrentSolution之前完成了TryApplyChanges),或者仅添加了一个项目(如果两个调用都已达到_worksapce) .CurrentSolution之前已执行TryApplyChanges)。
第二个问题:如果我的理解是正确的,那么有什么最佳方法来避免这些并发问题? 我想唯一的真实方法是依次安排/执行每个修改,对吗?
例如,Visual Studio是如何做到的。对工作区的修改是否仅在分派器上完成?
谢谢
基础代码是线程安全的,但您的用法不是。
如果同时更改解决方案,则TryApplyChanges()
将返回false。 如果发生这种情况,您需要再次尝试更改(从新的CurrentSolution
)。
基本上,你需要写
Solution changed;
do {
changed = _workspace.CurrentSolution....();
} while (!_workspace.TryApplyChanges(changed);
这称为比较交换循环; 有关更多详细信息,请参见我的博客 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.