同一台机器,不同的应用程序域,出现相同的 GUID
Same machine, different app domains, same GUIDs coming up
我很确定我要么做错了什么,要么理解错了。很难给出一段代码来说明我的问题,所以我将尝试解释我的场景,并给出结果。
我正在同一个控制台应用程序中启动 DLL 的多个实例,但在它自己的应用程序域中。然后我生成了一个 Guid.NewGuid() 分配给实例中的 class ,并将应用程序的文件夹设置为一个新文件夹。到目前为止效果很好。我可以看到一切正常,我的实例是分开的。但是......当我开始将我的应用程序文件夹更改为与为该 class 生成的唯一 GUID 同名时,我开始发现异常。
它工作正常,当我缓慢地实例化新实例时,但是当我敲入新实例时,应用程序在启动时开始在其文件夹中获取数据。经过一些调查,我发现这是因为那个文件夹已经存在,因为那个 GUID 已经被实例化了。在进一步调查中,我可以看到机器稍作停顿,然后继续生成新实例,所有实例都具有相同的 GUID。
我知道 GUID 生成算法使用 MAC 作为它的一部分,但我的印象是即使同一台机器在同一时刻生成两个 GUID,它仍然是独一无二。
我的说法正确吗?我哪里错了?
代码:
Guid guid = Guid.NewGuid();
string myFolder = Path.Combine(baseFolder, guid.ToString());
AppDomain ad = AppDomain.CurrentDomain;
Console.WriteLine($"{ad.Id} - {guid.ToString()}");
string newHiveDll = Path.Combine(myFolder, "HiveDriveLibrary.dll");
if (!Directory.Exists(myFolder))
{
Directory.CreateDirectory(myFolder);
}
if (!File.Exists(newHiveDll))
{
File.Copy(hiveDll, newHiveDll);
}
Directory.SetCurrentDirectory(myFolder);
var client = ServiceHelper.CreateServiceClient(serviceURL);
ElementConfig config = new ElementConfig();
ElementConfig fromFile = ElementConfigManager.GetElementConfig();
if (fromFile == null)
{
config.ElementGUID = guid;
config.LocalServiceURL = serviceURL;
config.RegisterURL = registerServiceURL;
}
else
{
config = fromFile;
}
Directory.SetCurrentDirectory
is a thin wrapper atop the Kernel 32 function SetCurrentDirectory
.
不幸的是,.NET documentation writers didn't choose to copy the warning from the native function:
Multithreaded applications and shared library code should not use the SetCurrentDirectory function and should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value
正是您对这个函数的依赖造成了多个线程神奇地选择了完全相同的 GUID 值的现象。
我很确定我要么做错了什么,要么理解错了。很难给出一段代码来说明我的问题,所以我将尝试解释我的场景,并给出结果。
我正在同一个控制台应用程序中启动 DLL 的多个实例,但在它自己的应用程序域中。然后我生成了一个 Guid.NewGuid() 分配给实例中的 class ,并将应用程序的文件夹设置为一个新文件夹。到目前为止效果很好。我可以看到一切正常,我的实例是分开的。但是......当我开始将我的应用程序文件夹更改为与为该 class 生成的唯一 GUID 同名时,我开始发现异常。
它工作正常,当我缓慢地实例化新实例时,但是当我敲入新实例时,应用程序在启动时开始在其文件夹中获取数据。经过一些调查,我发现这是因为那个文件夹已经存在,因为那个 GUID 已经被实例化了。在进一步调查中,我可以看到机器稍作停顿,然后继续生成新实例,所有实例都具有相同的 GUID。
我知道 GUID 生成算法使用 MAC 作为它的一部分,但我的印象是即使同一台机器在同一时刻生成两个 GUID,它仍然是独一无二。
我的说法正确吗?我哪里错了?
代码:
Guid guid = Guid.NewGuid();
string myFolder = Path.Combine(baseFolder, guid.ToString());
AppDomain ad = AppDomain.CurrentDomain;
Console.WriteLine($"{ad.Id} - {guid.ToString()}");
string newHiveDll = Path.Combine(myFolder, "HiveDriveLibrary.dll");
if (!Directory.Exists(myFolder))
{
Directory.CreateDirectory(myFolder);
}
if (!File.Exists(newHiveDll))
{
File.Copy(hiveDll, newHiveDll);
}
Directory.SetCurrentDirectory(myFolder);
var client = ServiceHelper.CreateServiceClient(serviceURL);
ElementConfig config = new ElementConfig();
ElementConfig fromFile = ElementConfigManager.GetElementConfig();
if (fromFile == null)
{
config.ElementGUID = guid;
config.LocalServiceURL = serviceURL;
config.RegisterURL = registerServiceURL;
}
else
{
config = fromFile;
}
Directory.SetCurrentDirectory
is a thin wrapper atop the Kernel 32 function SetCurrentDirectory
.
不幸的是,.NET documentation writers didn't choose to copy the warning from the native function:
Multithreaded applications and shared library code should not use the SetCurrentDirectory function and should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value
正是您对这个函数的依赖造成了多个线程神奇地选择了完全相同的 GUID 值的现象。