我可以安全地尝试从两个不同的线程创建相同的目录,而其中一个不会引发异常或遇到其他问题吗?
请注意,根据MSDN,可以调用CreateDirectory()
已经存在的目录,在这种情况下,该方法应该什么都不做。
我可以安全地尝试从两个不同的线程创建相同的目录,而其中一个不会引发异常或遇到其他问题吗?
请注意,根据MSDN,可以调用CreateDirectory()
已经存在的目录,在这种情况下,该方法应该什么都不做。
Directory.CreateDirectory
从多个线程进行调用本身是安全的。如果您这样做,它不会损坏程序或文件系统状态。
但是,不可能以Directory.CreateDirectory
这种方式调用以保证它不会引发异常。文件系统是一个不可预知的野兽,可以在任何给定时间被您无法控制的其他程序更改。例如,很可能会发生以下情况
CreateDirectory
并c:\temp\foo
成功c:\temp
程序 2 线程 1:删除程序 1 用户的访问权限CreateDirectory
程序 1 线程 2:由于访问不足而调用和抛出简而言之,您必须假设Directory.CreateDirectory
,或者实际上任何涉及文件系统的函数,都可以并且将相应地抛出和处理。
来自目录上的 MSDN 文档:
此类型的任何公共静态(在 Visual Basic 中为 Shared)成员都是线程安全的。不保证任何实例成员都是线程安全的。
因此,由于 CreateDirectory 是静态的,是的,它是线程安全的。
也就是说:正如@JaredPar 指出的那样,线程安全问题并不是方法可以抛出异常的唯一原因。文件系统调用可能引发异常的原因有很多(在任何情况下,无论是否多线程),您需要考虑这些原因。
通过说它是线程安全的,我(和 MSDN)仅暗示对此的字面解释,即“此方法不会以可能导致无效状态、竞争条件或其他通常与不安全相关的不利影响的方式修改共享程序状态多线程代码”
为了详细说明@JaredPar 的答案,您手头上有一个竞争条件。如果第一次调用完全创建了文件夹,然后第二次调用才开始,一切都会好起来的。
但是,如果第二个调用在处理第一个调用时到达操作系统,则操作系统可能会因锁定问题而使第二个调用失败,并且您将收到异常。
它仍然是线程安全的,因为您不会创建任何不可预测的文件夹,或者根本没有文件夹。
详细说明 - 虽然我不能 100% 确定 Windows 在同时创建两次同一个文件夹时没有内部竞争条件,但我很确定您将无法通过这样做来丢弃磁盘,或者陷入僵局,两个创作都被卡死了。其中一个会成功,另一个会失败,但会创建文件夹。
所以你的启发式,只是为了绝对肯定,应该是这样的:
如果它不断失败(例如,连续 3 次),您手上还有另一个问题 - 没有文件夹权限、完整磁盘等。
顺便说一句,为什么不在应用程序开始运行时创建一次文件夹呢?