0

I am trying to open a .txt file for my UPW app.

string text;
private async void OpenFile(string fileName)
{            
   StorageFolder localFolder = await ApplicationData.Current.LocalFolder.GetFolderAsync("Beginner");
   try
   {
       StorageFile file = await localFolder.GetFileAsync(fileName + ".txt");                     
       text = await FileIO.ReadTextAsync(file);
       PrintMessage(text);
   }
   catch (Exception)
   {
      PrintMessage("Failed to load file");                
   }
}

public async void PrintMessage(string message)
{
   //Writes message
   MessageDialog msg = new MessageDialog(message);
   await msg.ShowAsync();
}  

public Main() 
{
   OpenFile("WordList");
   PrintMessage(text);
}

The code runs fine when I have PrintMessage(text); after ReadTextAsync. When I delete it, the program will freeze most of the time. When I run it in debugger, it mostly gets done, but sometimes it freezes at line StorageFile file = await localFolder.GetFileAsync(fileName + ".txt");. I believe there is some problem with async magic.

Also, the text variable in Main() is almost always null even though it should contain text of the file. All I need is a function that will reliably open a .txt file and return (either return return, or like this into global) content of that file. I tried using Task<> but I couldnt make it work either...

Edit: I tried

string text { get; set; }
public async void OpenFileAssist(string fileName)
    {
        await OpenFile(fileName);
    }

public async Task OpenFile(string fileName)
{
    StorageFolder localFolder = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFolderAsync("Beginner");
    try
    {
        StorageFile file = await localFolder.GetFileAsync(fileName + ".txt");
        text = await FileIO.ReadTextAsync(file);
    }
    catch (Exception)
    {
        PrintMessage("File does not exist");
    }
}

But it still does not work... When I call OpenFileAssist() from Main() the text variable is still null. :( If I open it in debugger and go step by step it works, though.

I got solution by using

private async void Page_Loaded(object sender, RoutedEventArgs e)

9motom6
  • 66
  • 8
  • Set your `async` methods return types to `Task`, does your debugger display any exceptions? You're also calling async code without awaiting it in `Main` which is why `PrintMessage` will return null. – ColinM Dec 02 '16 at 19:55
  • I tried using Task but it didnt help and I got stuck when I tried to return text. It was returing the Task, not string. (Cannot implicitly convert type 'System.Threading.Tasks.Task' to 'string'). The Print message works fine if I give it a string like PrintMessage("Hello") but the text variable is null – 9motom6 Dec 02 '16 at 20:02
  • If you're returning `Task` then you must call `OpenFile` from a different method (not the constructor) which is also `async`, and then `await` the call to `OpenFile` to unwrap the result, which is a `string` – ColinM Dec 02 '16 at 20:04
  • http://stackoverflow.com/questions/11316438/call-to-await-getfileasync-never-returns-and-app-hangs-in-winrt-app - this might help. Not sure if `OpenFile` is called as a result of an event triggered by the UI element to be executed in the UI context as mentioned in the post , but if so the post might give you an idea – Jaya Dec 02 '16 at 20:09
  • I tried using Task called by private async void `OpenFileAsync(string fileName) { await OpenFile(fileName); }` but it doesnt work either. The text is still null in main function – 9motom6 Dec 02 '16 at 20:13
  • `async void` is bad. Don't do it. Always return a `Task` or `Task` from your methods. – mason Dec 02 '16 at 20:28
  • Answer http://stackoverflow.com/questions/11316438/call-to-await-getfileasync-never-returns-and-app-hangs-in-winrt-app is quite simillar, but I cant use `text = await FileIO.ReadTextAsync(file).ConfigureAwait(false);` – 9motom6 Dec 02 '16 at 20:32
  • `Main` isn't a function, it's a constructor. The text is null there because you call `OpenFile` and immediately `PrintMessage` before `OpenFile` has completed and assigned a value to `text`. – ColinM Dec 03 '16 at 08:35

1 Answers1

0

See this page, especially the example using TaskScheduler.FromCurrentSynchronizationContext(). It helped me a lot.

Ash8087
  • 643
  • 6
  • 16