I have a regular .NET application. In this case I have a part that's being imported by MEF. It imports fine, but at a certain point, I want to save a List of objects to a file. In this case it's just saving a list of high scores:
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;
}
}
}
I'm getting a System.Security.SecurityException on the new FileStream line. The weird thing is that if I just replace this with a TextWriter, it works. I don't understand what I'm doing wrong.
EDIT: More info... when I put this code in the constructor, it executes. If you follow the call stack back (when breaking in the sample above), it appears to be executing on the GUI thread. Specifically the WPF dispatcher is running a get operation on a property based on the fact that a PropertyChanged event fired. So maybe it has to do with a GUI refresher in WPF not being allowed to do file I/O? This kind of make sense... you wouldn't want to lock up the GUI for something like a file write...