다음 클래스에 잠금을 적용하는 정확한 방법을 알아 내려고하고 있습니다. 간단히 말해서, 객체는 싱글 톤이며 생성 될 때 주어진 디렉토리의 xml 파일로부터 다양한 수의 메뉴를 만듭니다. 지금은 읽기 만 허용되므로 잠금이 발생하지 않습니다 (MSDN 상태 읽기는 사전에서 스레드로부터 안전합니다). 그러나 파일 시스템 감시자를 유선 연결하여 변경할 때 메뉴를 다시 빌드 할 수 있습니다. 읽기가 발생하는 두 개의 사전이 있으므로이 문제를 처리 할 수있는 방법이 필요합니다. Lock (this)을 사용할 수는 있지만 더 좋은 방법이 있습니까? 따라서, 내가 읽는 것을 고정시키고 싶은 유일한 시간은 업데이트가 일어날 때입니다 (ctor로 보임). 잠금 적용 위치 및 방법
public class XmlMenuProvider : IMenuProvider {
private readonly INavigationService navigation;
private readonly Dictionary<string, IEnumerable<MenuItem>> menus;
private readonly Dictionary<string, Dictionary<string, MenuItem>> menusLookup;
private readonly FileSystemWatcher monitor;
public XmlMenuProvider(string folderPath, INavigationService navigation)
{
this.navigation = navigation;
this.menusLookup = new Dictionary<string, Dictionary<string, MenuItem>>();
this.menus = LoadFromSourceDirectory(folderPath);
this.monitor.Changed += (o, e) => {
// TODO - Add Locking
};
}
public IEnumerable<MenuItem> GetMenuItems(string name) {
return menus[name];
}
public MenuItem FindItemByName(string menu, string name) {
return menusLookup[menu][name];
}
private Dictionary<string, IEnumerable<MenuItem>> LoadFromSourceDirectory(string folderPath) {
var menus = new Dictionary<string, IEnumerable<MenuItem>>();
foreach (var file in Directory.GetFiles(folderPath, "*.xml")) {
var root = XDocument.Load(file).Elements().First();
var name = root.Attribute("name").Value;
var lookup = new Dictionary<string, MenuItem>();
menusLookup.Add(name, lookup);
menus.Add(name, BuildMenuHiearchyFromElement(root, lookup, null));
}
return menus;
}
private IEnumerable<MenuItem> BuildMenuHiearchyFromElement(XElement element, Dictionary<string, MenuItem> lookup, MenuItem parent) {
return element.Elements("Item")
.Select(e => {
var mi = CreateMenuItemFromElement(e, lookup, parent);
lookup.Add(mi.Name, mi);
return mi;
}
).ToList();
}
private MenuItem CreateMenuItemFromElement(XElement element, Dictionary<string, MenuItem> lookup, MenuItem parent) {
var name = element.Attribute("Name").Value;
var display = element.Attribute("DisplayName").Value;
var isClickable = true;
var roles = element.Attribute("Roles").Value.Split(',');
if (roles.Length == 1 && roles.First() == string.Empty) {
roles = new string[] { };
}
var attrClick = element.Attribute("IsClickable");
if (attrClick != null) {
isClickable = bool.Parse(attrClick.Value);
}
var navigateUrl = string.Empty;
if (isClickable) {
navigateUrl = navigation.FetchDestination(name);
}
return new MenuItem(name, display, navigateUrl, isClickable, roles, x => BuildMenuHiearchyFromElement(element, lookup, x), parent);
}
}
가 감사 : 여기
시각적를위한 클래스입니다.
네, 그렇지만 읽기를 수행하는 두 가지 방법을 잠글 필요가 없습니까 ?? 바로 그 부분은 메뉴를 다시 작성할 때 잠글 때만 필요합니다. Lock (이)이 문제를 해결할 것입니다. – Marco
@Marco -'lock()'에 언급 된 * 인스턴스를 잠그지 않고 인스턴스에 고정시킵니다. 큰 차이. @ Felice - 왜 결코 '잠 가야합니까?' –
정적을 보호 할 때는'lock'을 정적으로, 인스턴스를 보호 할 때는 인스턴스에'lock'을 설정해야합니다. –