Frage

Ich habe eine regelmäßige .NET-Anwendung. In diesem Fall habe ich einen Teil, der von MEF importiert werden wird. Es importiert in Ordnung, aber an einem bestimmten Punkt, ich möchte eine Liste der Objekte in einer Datei speichern. In diesem Fall wird es zu speichern ist nur eine Liste von 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;
        }
    }

}

Ich erhalte eine System.Security.SecurityException auf die neue Filestream Linie. Das Seltsame ist, dass, wenn ich dies nur ersetzen mit einem Textwriter, es funktioniert. Ich verstehe nicht, was ich falsch mache.

Bearbeiten : Mehr Informationen ... wenn ich im Konstruktor diesen Code setzen, sie ausgeführt wird. Wenn Sie den Call-Stack zurück folgen (wenn in der Probe oben brechen), erscheint es auf dem GUI-Thread zu ausgeführt werden. Insbesondere wird der WPF-Dispatcher auf einem Grundstück eine get-Operation ausgeführt wird, basierend auf der Tatsache, dass ein Property Ereignis ausgelöst. Vielleicht hat es mit einer GUI-Auffrischung in WPF zu tun, nicht zu werden erlaubt zu tun, Datei-I / O? Diese Art von Sinn machen ... Sie würde nicht die GUI für so etwas wie eine Datei schreiben sperren wollen ...

War es hilfreich?

Lösung

Ich war in der Lage, es zu erhalten, indem man die Stream-Funktionalität auszuführen und sie auf einem „unsicheren“ Threadpool-Thread, wie diese setzen:

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

Natürlich, die eine ganze Reihe von wirklich schlechten Synchronisierungsprobleme hat, die ich habe, um aufzuräumen, aber es funktioniert. Ich denke, was ich tun werde innerhalb der Gewindesicherung ist und haben sie eine Kopie der Liste machen, dann schreiben Sie die Kopie auf der Festplatte. Ich werde des Loggers muss auch loszuwerden, da Sie nicht sicher, dass über mehrere Threads zugreifen können.

Wirklich wünschte, ich wüsste, warum ich hatte dies aber zu tun.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top