为什么我不能使用对象成员可支配的对象? [英] Why I can not use disposable objects in object members?

查看:120
本文介绍了为什么我不能使用对象成员可支配的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不希望添加的StreamWriter 参数写入到文件的程序,但是当我试图用一次性的StreamWriter那里我得到工作:

 键入System.ObjectDisposedException的未处理的异常mscorlib.dll中发生

其他信息:无法写入一个封闭的TextWriter。
 

code:

 让fileLogger = {
    新IFlog
        会员i.FLog级别的格式=
            使用文件=日志文件()
            Printf.kfprintf
                (有趣的F  - >
                    fprintfn文件[%s]的[%A]
                            < | level.ToString()
                            < | DateTime.Now
                    )文件(格式)
 

所以当我打电话鞭打方法两次我得到这一点。

我可以用它类似这样:成员i.FLog文件级别的格式和控制支配对象的顶层,但后来我失去了所有的抽象

有没有一些方法来使用这样的一次性的对象?或者我如何改变结构来避免将一次性参数到这个功能呢?

日志文件是:

 让可变LOGFILENAME =F.log的
让日志文件()=
    比赛File.Exists(LOGFILENAME)与
    |假 - > File.CreateText(LOGFILENAME)
    |真 - > File.AppendText(LOGFILENAME)
 

解决方案

你得到的异常,因为你传递给 Printf.kfprintf 被编译为一个封闭的功能捕捉引用您的文件变量 - 例如,你的的TextWriter 实例。一旦 Printf.kfprintf 返回,文件超出范围;编译器看到,它不是其他任何地方使用,因此插入了一些code调用上的的TextWriter 的Dispose()方法C $ C>。到时候你调用由鞭打返回关闭方法,文件已被设置成该异常。

这是一个比较容易直观一些code。这是怎样的F#编译器编译鞭打方法:

 成员i.FLog级别的格式=
    尝试
        让文件=日志文件()
        Printf.kfprintf
            (有趣的F  - >
                fprintfn文件[%s]的[%A]
                        < | level.ToString()
                        < | DateTime.Now
                )文件(格式)
    最后
        如果文件<> null,则file.Dispose()
 

您可以通过让鞭打实施的IDisposable 的声明类型,并且使<$ C $解决这个问题C>文件值类的一部分,而不是方法中声明它。当声明类型的的Dispose()方法被调用,它应该只需要调用 file.Dispose()。你还需要注意不要用你与鞭打产生的任何封闭您已经处理后的实例,虽然,否则你会最终与同例外,你现在看到的。

I don't want to add StreamWriter parameter to Write-To-File procedure but when I'm trying to work with disposable StreamWriter there I'm getting:

An unhandled exception of type 'System.ObjectDisposedException' occurred in mscorlib.dll

Additional information: Cannot write to a closed TextWriter.

code:

let fileLogger = {
    new IFlog with
        member i.FLog level format =
            use file = LogFile()
            Printf.kfprintf 
                (fun f -> 
                    fprintfn file "[%s][%A] " 
                            <| level.ToString()
                            <| DateTime.Now
                    ) file (format)

so when I call FLog method twice I get this.

I can use it alike this : member i.FLog file level format and control disposable object on top level but then I lose all the abstraction.

Is there some way to use disposable objects like that? Or how can I change architecture to avoid passing disposable parameter into this function?

LogFile is :

let mutable LogFileName = "F.log"
let LogFile() =
    match File.Exists(LogFileName) with
    | false -> File.CreateText(LogFileName)
    | true  -> File.AppendText(LogFileName)

解决方案

You're getting the exception because the function you pass to Printf.kfprintf is compiled as a closure which captures a reference to your file variable -- i.e., your TextWriter instance. Once Printf.kfprintf returns, file goes out of scope; the compiler sees that it is not used anywhere else and thus inserts some code to call the Dispose() method on the TextWriter. By the time you call the closure returned by the FLog method, file has already been disposed so the exception is raised.

It's a little easier to visualize with some code. This is how the F# compiler compiles the FLog method:

member i.FLog level format =
    try
        let file = LogFile()
        Printf.kfprintf 
            (fun f -> 
                fprintfn file "[%s][%A] " 
                        <| level.ToString()
                        <| DateTime.Now
                ) file (format)
    finally
        if file <> null then file.Dispose ()

You could fix this by having the declaring type of FLog implement IDisposable, and making the file value part of the class instead of declaring it within the method. When the declaring type's Dispose() method is called, it should just call file.Dispose(). You'll still need to take care not to use any closures you've created with FLog after you've disposed the instance though, or you'll end up with the same exception you're seeing now.

这篇关于为什么我不能使用对象成员可支配的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆