我试图通过SaveFileDailog获取文件路径,然后使用StreamWriter实际创建文件然后写入数据。但它不起作用。我得到一个例外,说该文件正由另一个进程使用。这没有任何意义,因为我已经处理了SaveFileDialog并运行了垃圾收集......
到目前为止,这是我的代码。
let dialog = new SaveFileDialog()
let result = dialog.ShowDialog()
let file =
match result with
| DialogResult.OK ->dialog.OpenFile()
| _ -> failwith "cancel"
let path = dialog.FileName
dialog.Dispose()
let result = null
let dialog = null
GC.Collect()
let writer = (File.CreateText(path))
我确信这只是愚蠢的事情,但我仍然希望得到帮助。
答案 0 :(得分:2)
此代码的主要问题是对dialog.OpenFile()
的调用。你为什么要这么做?你知道它的作用吗?
当它发生时(并在documentation中说明),OpenFile()
实际打开文件并返回一个准备使用的Stream
实例。但是,出于某种原因,您丢弃此流并尝试创建自己的流,当然,这会失败,因为该文件已经打开。
所以正确的代码就是这样:
let getStreamForSaving() =
use dialog = new SaveFileDialog()
match dialog.ShowDialog() with
| DialogResult.OK -> dialog.OpenFile()
| _ -> failwith "cancel"
(请注意使用use
- 在需要时自动调用.Dispose
的F#方式)
那就是它,不需要.Dispose
和null
来跳舞。
说到null
。正如您所假设的那样,将null
分配给变量dialog
和result
这两行,实际上并没有这样做。在F#中,除非您另行明确指定,否则所有let
- 绑定值都是不可变(如同,不能变异)。即使您确实另行指定,也可以使用&#34; destructive update operator&#34;来完成变异值。 <-
。
您的代码所做的是创建名为dialog
和result
的新值 - 完全独立,与旧版本无关。如果你仔细观察,你会发现他们甚至有不同的类型。这被称为&#34;阴影&#34; - 一个非常有用的东西,但与可变性或垃圾收集无关。