如何在MAUI Android中使用ListenableFuture(适用于ListenableWorker)?

问题描述 投票:0回答:1

这个问题有一个解决方法,只需使用

.Result
并使其同步,但我认为应该有一种正确的方法可以使用ListenableFuture在.NET MAUI中执行异步代码。

上下文:所以我正在制作一个定期运行的 Worker。它可能会调用

async
方法,例如从 Internet 获取结果。 Android 文档建议使用 ListenableWorkerthis SO 答案 也是如此。然而,MAUI/Xamarin 的“翻译”非常奇怪,我无法真正让它工作。

这是Android的代码:

public class CallbackWorker extends ListenableWorker {

    public CallbackWorker(Context context, WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public ListenableFuture<Result> startWork() {
        return CallbackToFutureAdapter.getFuture(completer -> {
            Callback callback = new Callback() {
                int successes = 0;

                @Override
                public void onFailure(Call call, IOException e) {
                    completer.setException(e);
                }

                @Override
                public void onResponse(Call call, Response response) {
                    successes++;
                    if (successes == 100) {
                        completer.set(Result.success());
                    }
                }
            };

            for (int i = 0; i < 100; i++) {
                downloadAsynchronously("https://www.example.com", callback);
            }
            return callback;
        });
    }
}

这是 Xamarin 的等效项,但签名似乎并不相同:

public class TestTask : ListenableWorker
{
    public TestTask(Context appContext, WorkerParameters workerParams) : base(appContext, workerParams)
    {
    }

    public override IListenableFuture StartWork()
    {
        return CallbackToFutureAdapter.GetFuture(new FutureCallback());
    }

    class FutureCallback : Java.Lang.Object, CallbackToFutureAdapter.IResolver
    {

        public Java.Lang.Object? AttachCompleter(CallbackToFutureAdapter.Completer p0)
        {
            // What is Callback here?
            // What do I put in here?
            // I want to do something like this:
            // await DoSomethingAsync();
            // Done
        }

    }

}

请告诉我如何在 .NET MAUI 中实现文档示例。

编辑:在尝试探索 API 时,我意识到他们确实有一个方便的扩展方法

GetAsync
,相反(Android
IListenableFuture
-> .NET
Task
),因此必须有一些简单的方法来转换我不知道的其他方式?例如:

var existingWorks = await man.GetWorkInfosByTag(WorkerTag).GetAsync() as IEnumerable<WorkInfo>;
if (existingWorks?.Any() == true) { return; }
android .net async-await maui
1个回答
0
投票

你可以让你的类继承类

ListenableWorker
并实现接口
CallbackToFutureAdapter.IResolver

请参考以下代码:

public class SimpleListenableWorker : ListenableWorker, CallbackToFutureAdapter.IResolver
    {
        public const string TAG = "SimpleListenableWorker";

        public SimpleListenableWorker(Context context, WorkerParameters workerParams) : 
            base(context, workerParams)
        {
        }

        public override IListenableFuture StartWork()
        {
            Log.Debug(TAG, "Started.");
            return CallbackToFutureAdapter.GetFuture(this);
        }

        public Object AttachCompleter(CallbackToFutureAdapter.Completer p0)
        {
            Log.Debug(TAG, $"Executing.");

            //Switch to background thread.
            Task.Run(async () =>
            {
                //Perform a process here, simulated by a delay for 5 seconds.

                var delaySeconds = 5;
                var progress = 0;
                var progressIncrement = 100 / delaySeconds;
                var dataBuilder = new Data.Builder();

                for (int i = 0; i < delaySeconds+1; i++)
                {
                    await Task.Delay(1000);
                    progress += progressIncrement;
                    dataBuilder.PutInt("Progress", progress);
                    SetProgressAsync(dataBuilder.Build());
                }

                Log.Debug(TAG, "Completed.");

                //Set a Success Result on the completer and return it.
                return p0.Set(Result.InvokeSuccess());
            });

            return TAG;
        }
    }

有关更多信息,您可以参考文章在 XAMARIN ANDROID 中使用 WORKMANAGER 和 LISTENABLEWORKER

© www.soinside.com 2019 - 2024. All rights reserved.