WinRT에 익숙하지 않습니다. 예기치 않은 동작이 발생했습니다. 나는 static
변수 _Verses
을 클래스의 정적 생성자에서 초기화했습니다. 그래서 예상되는 동작은 When is a static constructor called in C#?정적 변수 초기화의 예기치 않은 동작
에 설명 된대로 _Verses
정적 방법 첫 번째 참조 전에 초기화 될 것이다 그러나 나는 static async
기능 LoadData
(WinRT)를 호출 할 때 예외를 얻었다.
개체 참조가 개체의 인스턴스로 설정되지 않았습니다.
내 코드는 다음과 같습니다
async void DoInit()
{
await DigitalQuran.Book.CreateInstance();
}
같은 코드가 바탕 화면에서 작업하지만 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"));
}
}
나는 같은 기능
CreateInstance
를 호출합니다. 데스크탑
Book
클래스의 전체 코드
here하고
VerseCollection
클래스
here
는 편집이다 : 나는 디버거를 코드 예외가 발생하지 않습니다를 실행하면 전체 코드는 여기
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);
}
}
}
입니다. 이 화상하지만 실행되기 때문에 또한 예외 후 비주얼 스튜디오 라인 _Chapters[i] = new Chapter(i, e.Current);
(_Chapters
는 null
이다)
어떻게 _Verses를 초기화하는지 알지 못합니다. 비동기 작업을 사용하고 계신지요? 그렇다면 LoadData를 호출 할 때 비동기 작업이 완료되지 않았을 수 있습니다 ... – Gusman
정적 변수 –
의 초기화 코드를 볼 필요가 있습니다. _Verses가 비동기 작업을 사용하여 초기화되지 않았습니다. 그것은 단지 배열의 초기화입니다. 초기화 코드가 추가되었습니다. –