Xamarin Forms中的异步计时器

wh6knrhe  于 2023-05-21  发布在  其他
关注(0)|答案(1)|浏览(133)

我想实现一个异步版本的Device.StartTimer方法。原因是我需要回调来等待异步方法的布尔结果返回。
我不知道如何做到这一点,因为我不知道如何等待TaskCompletionSource的任务。结果是立即返回布尔值。

Device.StartTimer(TimeSpan.FromMilliseconds(500), () =>
{
    var retVal = false;

    Device.BeginInvokeOnMainThread(async () =>
    {
        TaskCompletionSource<bool> tcs = new();
        retVal = await this.RefreshAsync().ConfigureAwait(false);
        tcs.TrySetResult(retVal);
    });

    // How to await the TaskCompletionSource's Task ?

    return retVal;
});

编辑:我试图解决的业务问题是在iOS特定的代码中,显示一个吐司并等待其动画完成(alpha = 0)。

因为动画是完全异步的,所以我使用TaskCompletionSource并在完成处理程序中设置其结果,以在外部等待任务。
代码如下:

private static Task ShowAlertAsync(string message, double seconds, Alignements alignements)
{
    var preferredStyle = UIAlertControllerStyle.Alert;

    if ((alignements & Alignements.Bottom) != 0)
    {
        preferredStyle = UIAlertControllerStyle.ActionSheet;
    }

    TaskCompletionSource<bool> tcs = new();

    var toast = UIAlertController.Create("", message, preferredStyle);
    UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(toast, true, () =>
    {
        UICubicTimingParameters timing = new(UIViewAnimationCurve.EaseIn);
        UIViewPropertyAnimator animator = new(seconds, timing);
        animator.AddAnimations(() => { toast.View.Alpha = 0; });
        animator.AddCompletion((pos) =>
        {
            toast.DismissViewController(true, null);
            toast.Dispose();
            toast = null;
            tcs.TrySetResult(true);
        });
        animator.StartAnimation();
    });
    
    return tcs.Task;
}

基本上,上一个代码块中的RefreshAsync正在等待ShowAlertAsync

x8goxv8g

x8goxv8g1#

这部分代码:

Device.BeginInvokeOnMainThread(async () =>
    {
        TaskCompletionSource<bool> tcs = new();
        retVal = await this.RefreshAsync().ConfigureAwait(false);
        tcs.TrySetResult(retVal);
    });

    // How to await the TaskCompletionSource's Task ?

变更为:

await MainThread.InvokeOnMainThreadAsync( async () =>
    {
        TaskCompletionSource<bool> tcs = new();
        retVal = await this.RefreshAsync().ConfigureAwait(false);
        tcs.TrySetResult(retVal);
        await tcs.Task();   // await TaskCompletionSource's Task
    });

或者简单地说:

await MainThread.InvokeOnMainThreadAsync( async () =>
    {
        await this.RefreshAsync();
    });

相关问题