locked
WinRT Cascading async Calls RRS feed

  • Question

  •         private async void engine_SaveRequested(object sender, SaveRestoreEventArgs e)
            {
                await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
                {
                    //create a Saved Game folder for saving all the games to app local folder or open existing folder
                    var savedGameFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("SavedGame", CreationCollisionOption.OpenIfExists);
                    //set currently saved game folder name
                    string gameFolderName = DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + ".save";
                    //create folder for currently saved game in the SavedGame folder and append a integer value if file name exists 
                    var currentGameFolder = await savedGameFolder.CreateFolderAsync(gameFolderName, CreationCollisionOption.GenerateUniqueName);
                    //create currently saved game file in the currentGameFolder with the gameFolderName
                    var savedGameFile = await currentGameFolder.CreateFileAsync(gameFolderName, CreationCollisionOption.ReplaceExisting);
                    //open savedGameFile stream for writing
                    var stream = await savedGameFile.OpenStreamForWriteAsync();
                    e.Stream = stream;
                });
            }
    

    The above code does not compile.

    I've tried to work through it a number of ways, but a solution escapes me.

    The point of the function (called from a non-UI task thread) is to do the steps as a transaction. Each step in order with a result so that e.Stream has a file Stream.

    I can do this if I block the UI, but I don't want to block. I want it to just run through the statements as they are...I don't care if each statement is asynchronous as long as they run in order and don't end the engine_SaveRequested method until everything is done.

    Help?

    Dave

    Saturday, August 31, 2013 3:43 AM

All replies

  •         private async void engine_SaveRequested(object sender, SaveRestoreEventArgs e)
            {
                await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, async () =>
                {
                    //create a Saved Game folder for saving all the games to app local folder or open existing folder
                    var savedGameFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync("SavedGame", CreationCollisionOption.OpenIfExists);
                    //set currently saved game folder name
                    string gameFolderName = DateTime.Now.ToString("yyyy-MM-dd-hh-mm-ss") + ".save";
                    //create folder for currently saved game in the SavedGame folder and append a integer value if file name exists 
                    var currentGameFolder = await savedGameFolder.CreateFolderAsync(gameFolderName, CreationCollisionOption.GenerateUniqueName);
                    //create currently saved game file in the currentGameFolder with the gameFolderName
                    var savedGameFile = await currentGameFolder.CreateFileAsync(gameFolderName, CreationCollisionOption.ReplaceExisting);
                    //open savedGameFile stream for writing
                    var stream = await savedGameFile.OpenStreamForWriteAsync();
                    e.Stream = stream;
                });
            }

    The above code does not compile.

    Try to add async before "() =>". Also you can use TaskCompletionSource<T> for store your stream.


    • Edited by Oleg Kurzov Saturday, August 31, 2013 7:50 AM
    Saturday, August 31, 2013 5:58 AM
  • The problem is that engineSave_Requested is called from a non-UI thread virtual machine op code (shown below) is continuing without the Stream reference. SaveRequested is called which is the delegate for the engine_saveRequested method in my game page code. But as soon as any async method is hit in engine_SaveRequested, processing on op_save continues.

    I want the engine_SaveRequested code to run transactionally before returning to op_save.

            [Opcode(0x123, "save", 1, Rule = OpcodeRule.DelayedStore)]
            private void op_save(uint[] args)
            {
                if (nestingLevel == 0 && SaveRequested != null)
                {
                    SaveRestoreEventArgs e = new SaveRestoreEventArgs();
                    SaveRequested(this, e);
                    if (e.Stream != null)
                    {
                        try
                        {
                            SaveToStream(e.Stream, args[1], args[2]);
                        }
                        finally
                        {
                            e.Stream.Dispose();//.Close();
                        }
                        PerformDelayedStore(args[1], args[2], 0);
                        return;
                    }
                }
    
                // failed
                PerformDelayedStore(args[1], args[2], 1);
            }
    

    Sunday, September 1, 2013 6:16 PM
  • Hi, ChicagoDave

    You can use the async and await keywords to make asynchronous programming to your op_save method. Try to change your codes below:

    [Opcode(0x123, "save", 1, Rule = OpcodeRule.DelayedStore)]
            private async void op_save(uint[] args)
            {
                if (nestingLevel == 0 && SaveRequested != null)
                {
                    SaveRestoreEventArgs e = new SaveRestoreEventArgs();
                    await  SaveRequested(this, e);
                    if (e.Stream != null)
                    {
                        try
                        {
                            SaveToStream(e.Stream, args[1], args[2]);
                        }
                        finally
                        {
                            e.Stream.Dispose();//.Close();
                        }
                        PerformDelayedStore(args[1], args[2], 0);
                        return;
                    }
                }
    
                // failed
                PerformDelayedStore(args[1], args[2], 1);
            }
    

    Also, there is another asynchronous programming in WinRt. You can refer to the link below to get more information:

    http://msdn.microsoft.com/en-us/library/System.IAsyncResult.aspx

    Best Wishes!


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Wednesday, September 4, 2013 8:45 AM