【问题标题】:System.Security.SecurityException when creating a new FileStream创建新的 FileStream 时出现 System.Security.SecurityException
【发布时间】:2009-10-28 03:14:25
【问题描述】:

我有一个常规的 .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 中不允许执行文件 I/O 的 GUI 刷新有关?这是有道理的...您不会想锁定 GUI 以执行文件写入之类的操作...

【问题讨论】:

    标签: c# filestream mef securityexception


    【解决方案1】:

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

            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);
    

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-08
      • 2019-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      相关资源
      最近更新 更多