2014-01-20 3 views
2

[править] Я хочу уточнить, что NullReferenceException не происходит в пределах отправленного кода, но этот код какой-то образом возвращает нульNullReferenceException при чтении данных из локального хранилища

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

/// <summary> 
/// Gets the list of workouts using Lazy Loading. 
/// </summary> 
/// <remarks> 
/// This is the point of access for Workouts in this Page. 
/// </remarks> 
public List<WorkoutModel> Workouts 
{ 
    get 
    { 
     if (workouts == null || !workouts.Any()) 
     { 
      workouts = JsonFileHelper.LoadWorkouts(); 
     } 

     return workouts; 
    } 
} 

код JsonFileHelper, доступ здесь:

/// <summary> 
/// Retrieves all the workouts from local storage. 
/// </summary> 
/// <returns>The list of workouts.</returns> 
public static List<WorkoutModel> LoadWorkouts() 
{ 
    bool couldLoadFile = true; 
    List<WorkoutModel> workouts = new List<WorkoutModel>(); 

    StorageFolder localFolder = ApplicationData.Current.LocalFolder; 
    StorageFile textFile = null; 

    Task<List<WorkoutModel>> t = Task<List<WorkoutModel>>.Run(() => LoadWorkoutsAsync(textFile, localFolder, couldLoadFile)); 
    t.Wait(); 

    workouts = t.Result; 

    return workouts; 
} 

Что вызывает этот метод на фоне потока:

private static async Task<List<WorkoutModel>> LoadWorkoutsAsync(StorageFile textFile, StorageFolder localFolder, bool couldLoadFile) 
{ 
    List<WorkoutModel> workouts = new List<WorkoutModel>(); 

    if (localFolder != null) 
    { 
     try 
     { 
      textFile = await localFolder.GetFileAsync(AppResources.FileName); 
     } 
     catch (FileNotFoundException) 
     { 
      couldLoadFile = false; 
     } 

     if (couldLoadFile) 
     { 
      // Create and use a stream to the file atomically 
      using (IRandomAccessStream textStream = await textFile.OpenReadAsync()) 
      { 
       // Read the text stream atomically 
       using (DataReader textReader = new DataReader(textStream)) 
       { 
        uint length = (uint)textStream.Size; 
        await textReader.LoadAsync(length); 

        string data = textReader.ReadString(length); 

        workouts = JsonConvert.DeserializeObject<List<WorkoutModel>>(data); 
       } 
      } 
     } 
    } 

    return workouts; 
} 

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

Что может вызвать эту проблему?

+2

Почти все случаи исключения NullReferenceException одинаковы. См. «[Что такое исключение NullReferenceException в .NET?] (Http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net)» для некоторых советов. –

ответ

0

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

Код должен быть реструктурирован с переменными, предсказуемыми на всех путях. Это не удивительно, если вы получаете такие ошибки, как есть.

Исключение, отличное от FileNotFoundException, оставляет hasLoadFile как true и textFile как null, вызывая эту ошибку. Это может быть вашей ошибкой.

Если этого недостаточно, укажите, пожалуйста, трассировку стека.

+0

Кажется, проблема в том, что t.Result возвращает null как-то - не может думать о случае, когда ожидание на локальном хранилище для получения файла вызывает исключение, отличное от FileNotFoundException. –

0

Вместо использования Task.Wait вы должны попробовать Task.Result.

/// /// Извлекает все тренировки из локального хранилища. /// /// Список тренировок.

public static List<WorkoutModel> LoadWorkouts() 
{ 
    bool couldLoadFile = true; 
    List<WorkoutModel> workouts = new List<WorkoutModel>(); 

    StorageFolder localFolder = ApplicationData.Current.LocalFolder; 
    StorageFile textFile = null; 

    List<WorkoutModel> workouts = Task<List<WorkoutModel>>.Run(() => LoadWorkoutsAsync(textFile, localFolder, couldLoadFile)).Result; 

    return workouts; 
} 
Смежные вопросы