首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何防止类的方法在类准备好之前被调用?

如何防止类的方法在类准备好之前被调用?
EN

Stack Overflow用户
提问于 2010-06-21 07:24:04
回答 9查看 235关注 0票数 1

这是我的自定义"logger“类,它帮助我在我的项目中创建日志文件。

代码语言:javascript
复制
namespace MyProject
{
class Logger
{
    private FileInfo fFile;
    private DirectoryInfo dDir;

    /// <summary>Add a new entry to the log file.</summary>
    /// <param name="sData">The line to add.</param>
    public void Add(string sData)
    {
        DateTime CurrTime = DateTime.Now;

        if (fFile.Length > 1048576)
        {
            fFile.MoveTo(Path.Combine(dDir.FullName, CurrTime.ToShortDateString() + fFile.Name));
            fFile = new FileInfo(Path.Combine(dDir.FullName,fFile.Name));
            using (StreamWriter sw = fFile.CreateText())
            {
                sw.WriteLine("{0:u}|{1}", CurrTime, sData);
            }
        }
        else
        {
            using (StreamWriter sw = fFile.AppendText())
            {
                sw.WriteLine("{0:u}|{1}", CurrTime, sData);
            }
        }
    }

    /// <summary>Logger instance</summary>
    /// <param name="sFile">Full name of the file to use as logs. Ex : "MyLogs.txt"</param>
    public Logger(string sFile)
    {
        dDir = new DirectoryInfo(Path.Combine(MyProject.AppPath, "logs"));
        if (!dDir.Exists)
        {
            dDir.Create();
        }

        fFile = new FileInfo(Path.Combine(dDir.FullName,sFile));

        if (!fFile.Exists)
        {
            using (StreamWriter sw = fFile.CreateText())
            {
                sw.WriteLine("{0:u}|Logger Started", DateTime.Now);
            }
        }
        else
        {
            Add("Logger Started");
        }           
    }
}
}

我在这段代码中遇到的问题显然是,有时在记录器的新实例有时间创建文件之前就调用了Logger.Add。所以我的程序崩溃了,说“文件找不到”,尽管文件最终还是被创建了,如果我用相同的日志文件名重新启动我的程序,一切正常(因为文件现在存在了……)

有没有一种方法可以“锁定”类,而不是在创建文件之前确保logger.add不被调用?

我试过锁的方法,但不起作用...Lock(this)没有做任何事情,而且我不能在方法本身上使用它。

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2010-06-22 18:26:24

该异常实际上并不是因为该文件不存在,而是因为FileInfo实例已过时!您在文件不存在的时候创建了FileInfo,它会获取该文件此时状态的快照。当我测试它时,当您在Add方法中调用fFile.Length时抛出异常。如果我添加一个对fFile.Refresh()的调用,我发现它可以工作:

代码语言:javascript
复制
...
DateTime currTime = DateTime.Now;
fFile.Refresh();
if (fFile.Length > 1048576)
...

请看这里:

http://msdn.microsoft.com/en-us/library/system.io.filesysteminfo.refresh.aspx

在尝试获取属性信息之前,必须先调用Refresh,否则信息将过时。

票数 2
EN

Stack Overflow用户

发布于 2010-06-21 07:56:53

问题是IO操作已被缓存。这在理论上不应该是一个问题,但实际上是一个问题。

您可以在构造函数中调用sw.Flush()。这将强制文件从缓存到磁盘,从而创建文件。

代码语言:javascript
复制
if (!fFile.Exists) 
{ 
    using (StreamWriter sw = fFile.CreateText()) 
    { 
        sw.WriteLine("{0:u}|Logger Started", DateTime.Now); 
        sw.Flush();
    } 
}
票数 2
EN

Stack Overflow用户

发布于 2010-06-21 07:29:42

就我个人而言,我不会走这条路,因为锁住了类。我将取出创建日志文件的代码,并使其成为自己的方法。然后,当调用add方法时,添加一些逻辑来检查日志文件是否存在(在我看来,这个逻辑也应该是它自己的方法)。如果该文件存在,则继续进行日志记录,如果不存在,则创建日志文件(使用上面提取的方法),然后在该方法成功返回后,继续写入日志。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3081304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档