C# Xamarin表单与Dispatcher.PushFrame的等价物是什么?

C# Xamarin表单与Dispatcher.PushFrame的等价物是什么?,c#,wpf,xamarin,async-await,C#,Wpf,Xamarin,Async Await,在我的WPF应用程序中,我有以下代码,可以从UI线程上的非异步函数调用并等待asnyc函数,而不会阻塞它。这是通过使用DispatcherFrame在后台泵送消息来完成的: public static void WaitWithPumping(this Task task) { if (task == null) throw new ArgumentNullException(“task”); var nestedFrame = new DispatcherFrame();

在我的WPF应用程序中,我有以下代码,可以从UI线程上的非异步函数调用并等待asnyc函数,而不会阻塞它。这是通过使用DispatcherFrame在后台泵送消息来完成的:

public static void WaitWithPumping(this Task task)
{
    if (task == null) throw new ArgumentNullException(“task”);
    var nestedFrame = new DispatcherFrame();
    task.ContinueWith(_ => nestedFrame.Continue = false);
    Dispatcher.PushFrame(nestedFrame);
    task.Wait();
}


public static T ResultWithPumping<T>(this Task<T> task)
{
    if (task == null) throw new ArgumentNullException(“task”);
    var nestedFrame = new DispatcherFrame();
    task.ContinueWith(_ => nestedFrame.Continue = false);
    Dispatcher.PushFrame(nestedFrame);
    return task.Result;
}
编辑#1:更新的示例。我知道这个例子有点站不住脚。为什么我不将RunTasks更改为async?或者只在后台线程上运行ProcessAsync()?嗯,我正在处理一个遗留项目(当然),RunTasks是一个LUA脚本处理引擎,它调用我的C#代码,还直接操作UI,因此它必须在UI线程上运行,而且设计上是非异步的。改变它将是一项巨大的工作。但是我的其余代码是异步的,我可以通过使用消息泵送方法轻松地在WPF中解决这个问题。

尝试下面的代码:

public static Task<T> BeginInvokeOnMainThreadAsync<T>(Func<T> a)
{
var tcs = new TaskCompletionSource<T>();
Device.BeginInvokeOnMainThread(() =>
    {
        try
        {
            var result = a();
            tcs.SetResult(result);
        }
        catch (Exception ex)
        {
            tcs.SetException(ex);
        }
    });
return tcs.Task;
}
公共静态任务BeginInvokeOnMainThreadAsync(Func a)
{
var tcs=new TaskCompletionSource();
Device.beginInvokeMainThread(()=>
{
尝试
{
var result=a();
tcs.SetResult(结果);
}
捕获(例外情况除外)
{
tcs.SetException(ex);
}
});
返回tcs.Task;
}

我无法使用BeginInvokeOnMainThread,因为它不返回结果(在asnyc函数返回任务的情况下)。我也不能使用InvokeOnMainThreadAsync,因为我不能从非异步函数等待它,使用Wait会使UI线程死锁。我怀疑我需要使用Looper和nsrunlop来实现我想要的,但我还不知道如何…但我应该如何调用它?我可以使用Wait或Result,我想它可以在后台线程上正常工作,但是如果我从UI线程调用它,它会死锁。
public static Task<T> BeginInvokeOnMainThreadAsync<T>(Func<T> a)
{
var tcs = new TaskCompletionSource<T>();
Device.BeginInvokeOnMainThread(() =>
    {
        try
        {
            var result = a();
            tcs.SetResult(result);
        }
        catch (Exception ex)
        {
            tcs.SetException(ex);
        }
    });
return tcs.Task;
}