What are your thoughts on using TaskCompletionSource in Xamarin as a way to let a Page know when a child page is complete?

Joe Harvey 0 Reputation points
2023-09-18T19:12:54.4666667+00:00

Hello Xam Team,

I have an interesting Scenario that I have never seen before and it smells to me, but I would like some other expects to weigh in on it.

Lets say I have a page, and that page will navigate to a new page Via Modal, but I would like to know when that new page is finished being displayed. Normally I would use events, or messaging services, but in this code I've found the use of TaskCompletionSource where on page Disappearing the a method of SetResult or Cancel is called on the TaskCompletionSource and the calling page receives the result.

Would using TaskCompletionSource to return results be dangerous or genius?

Basically, the code looks like the below, where the calling page would subscribe to the await

return await this.resultSource.Task;

protected virtual async Task<TResult> ShowDialogAsync()
        {
            if (this.resultSource != null)
                return await this.resultSource.Task;
 
            this.resultSource = new TaskCompletionSource<TResult>();
 
            try
            {
                await ShowAsync();
 
                return await this.resultSource.Task;
            }
            finally
            {
                this.resultSource = null;
                await HideAsync();
            }
        }
 
        protected void SetResult(TResult result)
        {
            this.resultSource?.SetResult(result);
            this.resultSource = null;
        }
        public virtual void Cancel()
        {
            this.resultSource?.TrySetCanceled();
            this.resultSource = null;
        }

There is a certain amount of creativity to this, but awaiting a UI operation seems very dangerous to me, and makes the code more difficult to maintain. Does anyone have any feedback on this?

Developer technologies | .NET | Xamarin
{count} votes

1 answer

Sort by: Most helpful
  1. Yonglun Liu (Shanghai Wicresoft Co,.Ltd.) 50,126 Reputation points Microsoft External Staff
    2023-09-19T03:29:25.2433333+00:00

    Hello,

    According to the TaskCompletionSource<TResult> Class, you can see the following remarks:

    In many scenarios, it is useful to enable a Task<TResult> to represent an external asynchronous operation. TaskCompletionSource<TResult> is provided for this purpose. It enables the creation of a task that can be handed out to consumers. The consumers can use the members of the task the same way as they would in any other scenario handling task member variables. However, unlike most tasks, the state of a task created by a TaskCompletionSource is controlled explicitly by the methods on TaskCompletionSource. This enables the completion of the external asynchronous operation to be propagated to the underlying Task. The separation also ensures that consumers are not able to transition the state without access to the corresponding TaskCompletionSource. For more information, see the entry The Nature of TaskCompletionSource<TResult> in the Parallel Programming with .NET blog.

    Because the TaskCompletionSource class can convert asynchronous operations to Tasks, it can also be used for user interface interactions.

    For example, you could map the user's click interaction in a modal box to a Task through it. Not only is the code reduced, but it is also easier to read and more purposeful.

    Best Regards,

    Alec Liu.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.