C# 静态变量初始化的意外行为

C# 静态变量初始化的意外行为,c#,windows-runtime,winrt-async,C#,Windows Runtime,Winrt Async,我对温特不太熟悉。我遇到了意想不到的行为。我有一个static变量\Verses,它在类的静态构造函数中初始化。所以预期的行为是。将在第一次引用静态方法之前初始化,如中所述 但当我调用一个静态异步函数加载数据(WinRT)时,我得到了一个异常 对象引用未设置为对象的实例。 我的代码是: public VerseCollection { public const int TotalVerses = 6236; static Verse[] _Verses; static Ver

我对温特不太熟悉。我遇到了意想不到的行为。我有一个
static
变量
\Verses
,它在类的静态构造函数中初始化。所以预期的行为是
将在第一次引用静态方法之前初始化,如中所述

但当我调用一个
静态异步
函数
加载数据
(WinRT)时,我得到了一个异常

对象引用未设置为对象的实例。

我的代码是:

public VerseCollection
{
   public const int TotalVerses = 6236;

   static Verse[] _Verses;
   static VerseCollection()
   {
        _Verses = new Verse[TotalVerses];
   }

   internal static async void LoadData(StorageFile file)
   {
      using (var reader = new BinaryReader(await file.OpenStreamForReadAsync()))
      {
           int wId = 0;
           for (int i = 0; i < VerseCollection.TotalVerses; i++)
           {
               var retValue = new string[reader.ReadInt32()];
               for (int j = 0; j < retValue.Length; j++)
                    retValue[j] = reader.ReadString();

               _Verses[i] = new Verse(i, wId, retValue);

               wId += _Verses[i].Words.Count;
           }
       }
   }
}

public Book
{    
   public static async Task<Book> CreateInstance()
   {
       VerseCollection.LoadData(await DigitalQuranDirectories.Data.GetFileAsync("quran-uthmani.bin"));
   }
}
相同的代码在桌面上工作,但不适用于WinRT。桌面版的书籍类的完整代码为,而与收藏版的类的完整代码为

编辑: 完整的代码在这里

public class Book : VerseSpan
{
    public static async Task<Book> CreateInstance()
    {
        _Instance = new Book();

        VerseCollection.LoadData(await DigitalQuranDirectories.Data.GetFileAsync("quran-uthmani.bin"));
        PrivateStorage.LoadQuranObjectsFromMetadata();
        // Some Other Operations too

        return _Instance;
    }
}


public class VerseCollection
{
    static Verse[] _Verses = new Verse[TotalVerses];

    internal static async void LoadData(StorageFile file)
    {
        using (var reader = new BinaryReader(await file.OpenStreamForReadAsync()))
        {
            int wId = 0;
            for (int i = 0; i < VerseCollection.TotalVerses; i++)
            {
                var retValue = new string[reader.ReadInt32()];
                for (int j = 0; j < retValue.Length; j++)
                    retValue[j] = reader.ReadString();

                _Verses[i] = new Verse(i, wId, retValue);

                wId += _Verses[i].Words.Count;
            }
        }
    }
}

public class Verse 
{
    public Verse(int number, int firstWordIndex, string[] words)
    {
        GlobalNumber = number + 1;

        Words = new WordCollection(firstWordIndex, words, this);            
    }
}

public class WordCollection : ReadOnlyCollection<Word>
{
    public const int TotalWords = 77878;

    static Word[] _Words = new Word[TotalWords];
    static string[] _WordsText = new string[TotalWords];

    public WordCollection(int startIndex, int count)
        : base(count)
    {
        this.startIndex = startIndex;
    }

    internal WordCollection(int startId, string[] words, Verse verse) : this(startId, words.Length)
    {
        int max = words.Length + startId;
        for (int i = startId; i < max; i++)
        {
            _Words[i] = new Word(i, verse);
            _WordsText[i] = words[i - startId];            
        }
    }
}

public abstract class ReadOnlyCollection<T> : IEnumerable<T>
{
    public ReadOnlyCollection(int count)
    {
        Count = count;
    }
}

public class PrivateStorage
{
    internal static async void LoadQuranObjectsFromMetadata()
    {            
        using (var reader = new BinaryReader(await (await DigitalQuranDirectories.Data.GetFileAsync(".metadata")).OpenStreamForReadAsync()))
        {
            /* 1 */ ChapterCollection.LoadData(EnumerateChapters(reader));
            /* 2 */ PartCollection.LoadData(EnumerateParts(reader));
            /* Some other tasks */
        }
    }

    static IEnumerator<ChapterMeta> EnumerateChapters(BinaryReader reader)
    {
        for (int i = 0; i < ChapterCollection.TotalChapters; i++)
        {
            yield return new ChapterMeta()
            {
                StartVerse = reader.ReadInt32(),
                VerseCount = reader.ReadInt32(),
                BowingCount = reader.ReadInt32(),
                Name = reader.ReadString(),
                EnglishName = reader.ReadString(),
                TransliteratedName = reader.ReadString(),
                RevelationPlace = (RevelationPlace)reader.ReadByte(),
                RevelationOrder = reader.ReadInt32()
            };
        }
    }

    static IEnumerator<PartMeta> EnumerateParts(BinaryReader reader)
    {
        for (int i = 0; i < PartCollection.TotalParts; i++)
        {
            yield return new PartMeta()
            {
                StartVerse = reader.ReadInt32(),
                VerseCount = reader.ReadInt32(),
                ArabicName = reader.ReadString(),
                TransliteratedName = reader.ReadString()
            };
        }
    }
}


public class ChapterCollection : ReadOnlyCollection<Chapter>
{
    public const int TotalChapters = 114;

    static Chapter[] _Chapters = new Chapter[TotalChapters];

    internal static void LoadData(IEnumerator<ChapterMeta> e)
    {
        for (int i = 0; i < TotalChapters; i++)
        {
            e.MoveNext();
            _Chapters[i] = new Chapter(i, e.Current);
        }
    }
}


public class PartCollection : ReadOnlyCollection<Part>
{
    public const int TotalParts = 30;

    static Part[] _Parts = new Part[TotalParts];
    internal static void LoadData(IEnumerator<PartMeta> e)
    {            
        for (int i = 0; i < TotalParts; i++)
        {
            e.MoveNext();
            _Parts[i] = new Part(i, e.Current);
        }
    }
}
公共课堂教材:VerseSpan
{
公共静态异步任务CreateInstance()
{
_实例=新书();
加载数据(等待DigitalQuranDirectories.Data.GetFileAsync(“quran-uthmani.bin”);
PrivateStorage.LoadQuranObjectsFromMetadata();
//还有其他一些行动
返回_实例;
}
}
公共课与集体课
{
静态韵文[]u韵文=新韵文[总韵文];
内部静态异步void LoadData(存储文件)
{
使用(var reader=new BinaryReader(wait file.OpenStreamForReadAsync()))
{
int-wId=0;
for(int i=0;i

当我使用调试器运行代码时,不会引发异常。此外,在异常发生后,visual studio在函数
加载数据
中的类
中显示了一些时间,这些时间在线
\u Verses[i]=new Verse(i,wId,retValue)
\u Verses
null
),有时在类中
章节集合
函数中
加载数据
在线
\u章节[i]=新章节(即当前)
\u Chapters
null

因为它在桌面上运行,而不是在WinRT上运行,这让我相信您的异步调用存在问题。由于您是异步执行此操作的,因此在调用LoadData之前,构造函数(静态或非静态)不会完成运行。在调用LoadData函数之前,请确保构造函数已完成执行,这将为您提供一致的行为。

public class Book : VerseSpan
{
    public static async Task<Book> CreateInstance()
    {
        _Instance = new Book();

        VerseCollection.LoadData(await DigitalQuranDirectories.Data.GetFileAsync("quran-uthmani.bin"));
        PrivateStorage.LoadQuranObjectsFromMetadata();
        // Some Other Operations too

        return _Instance;
    }
}


public class VerseCollection
{
    static Verse[] _Verses = new Verse[TotalVerses];

    internal static async void LoadData(StorageFile file)
    {
        using (var reader = new BinaryReader(await file.OpenStreamForReadAsync()))
        {
            int wId = 0;
            for (int i = 0; i < VerseCollection.TotalVerses; i++)
            {
                var retValue = new string[reader.ReadInt32()];
                for (int j = 0; j < retValue.Length; j++)
                    retValue[j] = reader.ReadString();

                _Verses[i] = new Verse(i, wId, retValue);

                wId += _Verses[i].Words.Count;
            }
        }
    }
}

public class Verse 
{
    public Verse(int number, int firstWordIndex, string[] words)
    {
        GlobalNumber = number + 1;

        Words = new WordCollection(firstWordIndex, words, this);            
    }
}

public class WordCollection : ReadOnlyCollection<Word>
{
    public const int TotalWords = 77878;

    static Word[] _Words = new Word[TotalWords];
    static string[] _WordsText = new string[TotalWords];

    public WordCollection(int startIndex, int count)
        : base(count)
    {
        this.startIndex = startIndex;
    }

    internal WordCollection(int startId, string[] words, Verse verse) : this(startId, words.Length)
    {
        int max = words.Length + startId;
        for (int i = startId; i < max; i++)
        {
            _Words[i] = new Word(i, verse);
            _WordsText[i] = words[i - startId];            
        }
    }
}

public abstract class ReadOnlyCollection<T> : IEnumerable<T>
{
    public ReadOnlyCollection(int count)
    {
        Count = count;
    }
}

public class PrivateStorage
{
    internal static async void LoadQuranObjectsFromMetadata()
    {            
        using (var reader = new BinaryReader(await (await DigitalQuranDirectories.Data.GetFileAsync(".metadata")).OpenStreamForReadAsync()))
        {
            /* 1 */ ChapterCollection.LoadData(EnumerateChapters(reader));
            /* 2 */ PartCollection.LoadData(EnumerateParts(reader));
            /* Some other tasks */
        }
    }

    static IEnumerator<ChapterMeta> EnumerateChapters(BinaryReader reader)
    {
        for (int i = 0; i < ChapterCollection.TotalChapters; i++)
        {
            yield return new ChapterMeta()
            {
                StartVerse = reader.ReadInt32(),
                VerseCount = reader.ReadInt32(),
                BowingCount = reader.ReadInt32(),
                Name = reader.ReadString(),
                EnglishName = reader.ReadString(),
                TransliteratedName = reader.ReadString(),
                RevelationPlace = (RevelationPlace)reader.ReadByte(),
                RevelationOrder = reader.ReadInt32()
            };
        }
    }

    static IEnumerator<PartMeta> EnumerateParts(BinaryReader reader)
    {
        for (int i = 0; i < PartCollection.TotalParts; i++)
        {
            yield return new PartMeta()
            {
                StartVerse = reader.ReadInt32(),
                VerseCount = reader.ReadInt32(),
                ArabicName = reader.ReadString(),
                TransliteratedName = reader.ReadString()
            };
        }
    }
}


public class ChapterCollection : ReadOnlyCollection<Chapter>
{
    public const int TotalChapters = 114;

    static Chapter[] _Chapters = new Chapter[TotalChapters];

    internal static void LoadData(IEnumerator<ChapterMeta> e)
    {
        for (int i = 0; i < TotalChapters; i++)
        {
            e.MoveNext();
            _Chapters[i] = new Chapter(i, e.Current);
        }
    }
}


public class PartCollection : ReadOnlyCollection<Part>
{
    public const int TotalParts = 30;

    static Part[] _Parts = new Part[TotalParts];
    internal static void LoadData(IEnumerator<PartMeta> e)
    {            
        for (int i = 0; i < TotalParts; i++)
        {
            e.MoveNext();
            _Parts[i] = new Part(i, e.Current);
        }
    }
}
public class Book : VerseSpan
{
    public static async Task<Book> CreateInstance()
    {
        _Instance = new Book();

        await VerseCollection.LoadData(await DigitalQuranDirectories.Data.GetFileAsync("quran-uthmani.bin"));
        await PrivateStorage.LoadQuranObjectsFromMetadata();
        // Some Other Operations too

        return _Instance;
    }
}


public class VerseCollection
{
    static Verse[] _Verses = new Verse[TotalVerses];

    internal static async Task LoadData(StorageFile file)
    {
        using (var reader = new BinaryReader(await file.OpenStreamForReadAsync()))
        {
            int wId = 0;
            for (int i = 0; i < VerseCollection.TotalVerses; i++)
            {
                var retValue = new string[reader.ReadInt32()];
                for (int j = 0; j < retValue.Length; j++)
                    retValue[j] = reader.ReadString();

                _Verses[i] = new Verse(i, wId, retValue);

                wId += _Verses[i].Words.Count;
            }
        }
    }
}

public class PrivateStorage
{
    internal static async Task LoadQuranObjectsFromMetadata()
    {            
        using (var reader = new BinaryReader(await (await DigitalQuranDirectories.Data.GetFileAsync(".metadata")).OpenStreamForReadAsync()))
        {
            /* Some tasks */
        }
    }
}