MS669
MS669

Reputation: 13

Async methods in callbacks

What I'm trying to do is make a background task that logs each unlock of the Phone but I can't get the writing to the log to work.

This is what how I'm registering a background Task:

public App()
    {
        this.InitializeComponent();
        this.Suspending += this.OnSuspending;

        backgroundTask = registerBackgroundTask();
    }

    private BackgroundTaskRegistration registerBackgroundTask()
    {
        // -----------------------------
        const string taskName = "BackgroundTask_Task";
        // -----------------------------


        IAsyncOperation<BackgroundAccessStatus> accessStatus = BackgroundExecutionManager.RequestAccessAsync();

        SystemTrigger systemTrigger = new SystemTrigger(SystemTriggerType.UserPresent, false);

        foreach( var cur in BackgroundTaskRegistration.AllTasks )
        {
            if( cur.Value.Name == taskName )
            {
                // The Task is already registered.
                return (BackgroundTaskRegistration)(cur.Value);
            }
        }

        BackgroundTaskBuilder builder = new BackgroundTaskBuilder();

        builder.Name = taskName;
        builder.TaskEntryPoint = typeof(BackgroundTask_Task.Task).FullName;
        builder.SetTrigger(systemTrigger);

        return builder.Register();

    }

And then im trying this:

public async void Run(IBackgroundTaskInstance taskInstance)
    {
        Debug.WriteLine("Test");
        Debug.WriteLine(DateTime.Now.ToString("g"));

        StorageFolder dataFolder = ApplicationData.Current.LocalFolder;
        StorageFile logFile = await dataFolder.CreateFileAsync("logFile.txt", CreationCollisionOption.OpenIfExists);

        IList<string> logLines = await FileIO.ReadLinesAsync(logFile);

        foreach( var s in logLines )
        {
            Debug.WriteLine(s);
        }

        logLines.Add(DateTime.Now.ToString("g"));
        if( logLines.Count > 5 )
        {
            logLines.RemoveAt(0);
        }

        await FileIO.AppendLinesAsync(logFile, logLines);

    }

But the problem is it will not read/write from logFile.txt. (Sometimes it did but not everytime).

I thought that I can't just make a system call async to use async methods in there which would make sense. But then I tried to run it into a async lamdbda with ThreadPool.RunAsync, no success either. What do you generally do when you want to call async methods in functions that are not async?

Upvotes: 0

Views: 77

Answers (1)

NeddySpaghetti
NeddySpaghetti

Reputation: 13495

As mentioned in this blog entry, the asynchronous work needs to be encapsulated in a background task deferral

public async void Run(IBackgroundTaskInstance taskInstance)
{
    BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();

    Debug.WriteLine("Test");
        Debug.WriteLine(DateTime.Now.ToString("g"));

        StorageFolder dataFolder = ApplicationData.Current.LocalFolder;
        StorageFile logFile = await dataFolder.CreateFileAsync("logFile.txt", CreationCollisionOption.OpenIfExists);

        IList<string> logLines = await FileIO.ReadLinesAsync(logFile);

        foreach( var s in logLines )
        {
            Debug.WriteLine(s);
        }

        logLines.Add(DateTime.Now.ToString("g"));
        if( logLines.Count > 5 )
        {
            logLines.RemoveAt(0);
        }

        await FileIO.AppendLinesAsync(logFile, logLines);

    _deferral.Complete(); 
}

Upvotes: 1

Related Questions