创建新FileStream时出现System.Security.SecurityException

时间:2009-10-28 03:14:26

标签: c# filestream mef securityexception

我有一个常规的.NET应用程序。在这种情况下,我有一个由MEF导入的部分。它输入正常,但在某一点上,我想将一个对象列表保存到一个文件。在这种情况下,它只是保存一个高分列表:

class HighScores
{
    static HighScores()
    {
        CheckTrust();
    }

    [ImportingConstructor]
    public HighScores(
         [Import("/Services/LoggingService", typeof(ILoggingService))] 
         ILoggingService l
        )
    {
        logger = l;

    }

    private ILoggingService logger { get; set; }

    public IEnumerable<HighScore> Scores
    {
        get
        {
            return m_Scores;
        }
    }
    private List<HighScore> m_ScoresUnsorted = new List<HighScore>();
    private readonly ObservableCollection<HighScore> m_Scores = 
        new ObservableCollection<HighScore>();

    public void LogNewHighScore(string name, int score, int level)
    {
        m_ScoresUnsorted.Add(new HighScore(name, score, level));
        CreateObservable();

        if (IsFullTrust)
        {
            Stream stream = null;
            try
            {
                // this line causes exception
                stream = new FileStream("HighScores.dat", 
                         System.IO.FileMode.Create, FileAccess.Write);  
                BinaryFormatter b = new BinaryFormatter();
                b.Serialize(stream, m_ScoresUnsorted);
            }
            catch (Exception e)
            {
                logger.Error("Error writing high scores:", e);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }
        }
    }

    private void CreateObservable()
    {
        m_ScoresUnsorted.Sort();
        m_Scores.Clear();
        for(int i = m_ScoresUnsorted.Count-1; i >= 0; i--)
        {
            m_Scores.Add(m_ScoresUnsorted[i]);
        }
    }

    static private void CheckTrust()
    {
        try
        {
            FileIOPermission permission =
                new FileIOPermission(PermissionState.Unrestricted);
            s_FullTrust = SecurityManager.IsGranted(permission);
        }
        catch (Exception)
        {
            // ignore
        }
    }

    static private bool s_FullTrust;
    static public bool IsFullTrust
    {
        get
        {
            return s_FullTrust;
        }
    }

}

我在新的FileStream行上遇到System.Security.SecurityException。奇怪的是,如果我用TextWriter替换它,它就可以了。我不明白我做错了什么。

编辑:更多信息...当我将此代码放在构造函数中时,它会执行。如果你追回调用堆栈(当破坏上面的示例时),它似乎正在GUI线程上执行。具体来说,WPF调度程序根据PropertyChanged事件触发的事实对属性运行get操作。那么也许它与WPF中的GUI刷新器不允许进行文件I / O有关?这样有意义......你不想为像文件写入这样的东西锁定GUI ......

1 个答案:

答案 0 :(得分:0)

我能够通过获取流功能并将其置于“不安全”的ThreadPool线程来执行它,如下所示:

        ThreadPool.UnsafeQueueUserWorkItem(ignoredState =>
        {
            Stream stream = null;
            try
            {
                stream = new FileStream("HighScores.dat", System.IO.FileMode.Create, FileAccess.Write);
                BinaryFormatter b = new BinaryFormatter();
                b.Serialize(stream, "Test String");
            }
            catch (Exception e)
            {
                logger.Error("Error writing high scores:", e);
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }
        }, null);

当然,这有很多非常糟糕的同步问题,我必须清理,但它确实有效。我想我要做的就是锁定线程内部并让它复制列表,然后将副本写入磁盘。我不得不摆脱记录器,因为你不能安全地访问多个线程。

真的希望我知道为什么我必须这样做。