4

好吧,伙计们,这是一个艰难的。

场景

  • 我有多个服务在多台机器上运行
  • 每个服务都有多个线程,每个线程在 FILER 上写入一个文件 - 我的机器使用的共享存储(使用 \\filername\foo\bar 等共享)
  • FILER 机器是 NetApp 机器
  • FILER 和运行服务的机器都使用 SMB2 (http://en.wikipedia.org/wiki/Server_Message_Block)
  • 用于写入文件的指令就像下面 [THE CODE] 中列出的指令一样简单

[编码]

using (StreamWriter outfile = new StreamWriter(pathToTheFile, false))
{
  outfile.Write(stringToWriteInTheFile);
}

[/编码]

问题

有时服务仍然“卡在”这个指令上。给出的错误是:

该进程无法访问文件 '\\filername\foo\bar\myfile.txt',因为它正被另一个进程使用。

在其中一些错误之后,服务拒绝释放文件上的锁定。那会发生什么?

您可以删除该文件,但该文件会立即重新创建。就像某种永久流还活着并且无限期地继续写入文件一样。

您可以停止服务:它被卡住了,并且不会停止,所以我在 2 分钟后强制执行 Thread.Abort(是的,我知道但练习,但还有什么?)。

因此,服务现在已停止,但机器保留了文件的句柄,并且您无法终止进程以保持句柄处于活动状态,除非重新启动机器。. .

我现在不知道该怎么办,我想我什么都试过了。

注意事项

以前,FILER和机器都使用SMB1,从来没有出现过这个问题。所以我猜背景中发生了一些可疑的事情,但我不明白是什么......

我最近更改了用于编写文件的代码,不顾一切地尝试将所有内容“委托”给.net。现在是:

File.WriteAllText(pathToTheFile, stringToWriteInTheFile);

但我的直觉是,在秘密下,.net 正在做同样的事情——虽然变化是最近才发生的,所以我仍然不能说“修复”是否有效。

编辑(根据 Vash 评论):通常文件是不同的,但有时可能会发生(并且实际上会发生)多个线程试图写入同一个文件,但是 :( - 执行 File.WriteAllText 不应该小心并发问题?

4

1 回答 1

2

尝试以“独占”模式显式打开 FileStream,即

using (var fs = new FileStream("path", 
                              FileMode.Open, FileAccess.ReadWrite, 
                              FileShare.None))
{
    using (var sw = new StreamWriter(fs))
    {
        ...

当然,您的代码必须预料到文件在写入并做出适当反应时可能会被锁定。这部分留给读者练习:-)

免责声明:我在多线程环境中使用过它,但我不能保证它可以在 Samba 上运行。

于 2011-04-18T16:13:48.460 回答