2009-10-28 4 views
1

У меня есть обычное приложение .NET. В этом случае у меня есть часть, которая импортируется MEF. Он импортирует штраф, но в определенный момент я хочу сохранить список объектов в файл. В этом случае это просто сохранение списка высокой оценки:System.Security.SecurityException при создании нового FileStream

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

} 

Я получаю System.Security.SecurityException на новой FileStream линии. Странно то, что если я просто заменю это на TextWriter, он будет работать. Я не понимаю, что я делаю неправильно.

EDIT: Дополнительная информация ... когда я помещаю этот код в конструктор, он выполняется. Если вы следуете за стеком вызовов назад (при разбиении на образец выше), он, похоже, выполняется в потоке графического интерфейса. В частности, диспетчер WPF запускает операцию get на свойстве, основанном на том, что событие PropertyChanged запускается. Может быть, это связано с обновлением графического интерфейса в WPF, который не разрешен для ввода/вывода файлов? Такой смысл ... вы не хотели бы блокировать GUI для чего-то вроде записи файла ...

ответ

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

конечно, что есть целая куча действительно плохие вопросы синхронизации, которые я должен убирать, но это работает. Я думаю, что я сделаю, это заблокировать внутри потока и сделать копию списка, а затем записать копию на диск. Я также должен избавиться от регистратора, так как вы не можете безопасно получить доступ к нему через несколько потоков.

На самом деле я знал, почему я должен был это сделать.

 Смежные вопросы

  • Нет связанных вопросов^_^