locked
[UWP]await problem RRS feed

  • Question

  • Greetings,

    I have this function:

    internal static async Task<StorageFile> CreateFileAsync(string path, CreationCollisionOption collisionOption)
    {
     string strFolder = Path.GetDirectoryName(path);
     string strFile = Path.GetFileName(path);
     StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(strFolder);
     StorageFile file = await folder.CreateFileAsync(strFile, collisionOption);
     return file;
    }
    ...
    CreateFileAsync().AsTask().Wait();

    The call await StorageFolder.GetFolderFromPathAsync(strFolder); blocks forever, the call to folder.CreateFileAsync() is never made, and the file is never created. There are no exceptions being thrown. If I change it this way, it works perfectly:

    internal static StorageFile CreateFile(string path, CreationCollisionOption collisionOption)
    {
     string strFolder = Path.GetDirectoryName(path);
     string strFile = Path.GetFileName(path);
     StorageFolder folder = StorageFolder.GetFolderFromPathAsync(strFolder).AsTask().Wait();;
     StorageFile file = folder.CreateFileAsync(strFile, collisionOption).AsTask().Wait();;
     return file;
    }
    ...
    CreateFile();

    Any ideas?

    Thank you.


    Tuesday, February 26, 2019 12:00 PM

All replies

  • Hi,

    That's normal.

    In your first code you mix awaitable code with the TPL.

    Your "CreateFileAsync()" method is "async" so this method became "awaitable" and use a specific context for sync the UI (event if the return type is a Task<>). When you call "CreateFileAsync().AsTask().Wait()" you create a Task (from the TPL library) and calling the "Wait()" method use the TPL sync context, which is not compatible with the awaitable context. The sync context never known that the async code is finished, so your code is blocked.

    Beware calling the "Task.Result" property cause the same behavior because is calling "Wait()".

    The second code has no problems because it use ony the TPL.

    The await/async code is viral, if you call an await/async method, your caller need to be awaitable. So why you want to wait ?

    Regards,


    Yan Grenier

    Merci de bien vouloir "Marquer comme réponse", les réponses qui ont répondues à votre question, et de noter les réponses que vous avez trouvé utiles.

    Tuesday, February 26, 2019 1:36 PM
  • Thanks Yan, but it's still not 100% clear to me. I thought the second await statement would wait for the first one to finish, since it uses the "folder" variable. But my impression is that the second await statement is never executed, because the file is never created.

    How do you think the first code should be fixed in order to make it work? I absolutely need to wait for my function to finish before going on.

    Thanks again.

    Tuesday, February 26, 2019 2:31 PM
  • Since the await/async and TPL are not compatible, it's probably blocked on the first "await", so the second "await" is never called so your file is never created.

    You can't fix that, you need to use the await/async pattern on all your calls chain. You can use the TPL pattern instead of, but it's more complicated to sync the UI in this case, it's why the await/async pattern was created.

    Why "I absolutely need to wait..." ? You just need to make your first caller awaitable to wait the end of this code.

    Regards,


    Yan Grenier

    Merci de bien vouloir "Marquer comme réponse", les réponses qui ont répondues à votre question, et de noter les réponses que vous avez trouvé utiles.

    Tuesday, February 26, 2019 4:31 PM