繁体   English   中英

CreateDirectory()在C#中是否是线程安全的?

[英]Is CreateDirectory() in C# thread-safe?

我可以安全地尝试从两个不同的线程创建相同的目录,而不会让其中一个抛出异常,或遇到其他问题吗?

请注意,根据MSDN ,可以在已存在的目录上调用CreateDirectory() ,在这种情况下,该方法不会执行任何操作。

Directory.CreateDirectory调用本身可以安全地从多个线程进行。 如果这样做,它不会破坏程序或文件系统状态。

但是,无法以这种方式调用Directory.CreateDirectory以保证它不会抛出异常。 文件系统是一个不可预测的野兽,可以在任何给定时间由您控制之外的其他程序更改。 例如,很可能看到以下情况发生

  • 程序1线程1:为c:\\temp\\foo调用CreateDirectory并成功
  • 程序2线程1:从程序1用户中删除对c:\\temp访问权限
  • 程序1线程2:调用CreateDirectory并因访问不足而抛出

简而言之,您必须假设Directory.CreateDirectory ,或者实际上任何触及文件系统的函数都可以并且将相应地抛出和处理。

目录上MSDN文档

此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的。 任何实例成员都不保证是线程安全的。

因此,由于CreateDirectory是静态的,是的,它是线程安全的。

这就是说 :正如@JaredPar指出的那样,线程安全问题并不是方法抛出异常的唯一原因。 文件系统调用可能会抛出异常(在任何情况下,多线程或非多线程),并且您需要考虑这些原因,这有很多原因。

通过说它是线程安全的I(和MSDN)只暗示对它的字面解释,意思是“此方法不会以可能导致无效状态,竞争条件或通常与不安全相关的其他不利影响的方式修改共享程序状态多线程代码“

要详细说明@JaredPar的答案,你手上就有竞争条件。 如果第一个呼叫完全创建了文件夹,只有第二个呼叫开始,一切都会正常。

但是,如果第二个呼叫在仍处理第一个呼叫时到达操作系统,则操作系统可能会使第二个呼叫失败以锁定问题,并且您将获得异常。

它仍然是线程安全的,因为您不会创建任何不可预测的文件夹,或根本没有文件夹。

详细说明 - 虽然我并非100%确定Windows在同时创建两个同一文件夹时没有内部竞争条件,但我很确定你无法通过这样做来废弃磁盘,或者两个创作都陷入死亡之中陷入僵局。 其中一个会成功,另一个会失败,但会创建文件夹。

所以你的启发式,只是为了绝对肯定,应该是这样的:

  • 创建目录
  • 如果失败,请等待一段随机时间(例如,在0.2到0.5秒之间),然后再试一次。
  • 如果它经常失败(例如,连续3次),你手上还有另一个问题 - 对文件夹,完整磁盘等没有权限。

    顺便提一下,为什么不在应用程序开始运行时创建文件夹?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM