Xamarin: как перерисовать пользовательский интерфейс при выполнении длительной операции в потоке пользовательского интерфейса (без использования async / await) - PullRequest
0 голосов
/ 03 ноября 2018

Я (по причинам) вынужден выполнять длительную операцию в потоке пользовательского интерфейса моего приложения форм xamarin (NetStandard). Во время этой операции я хотел бы обновить пользовательский интерфейс, чтобы дать пользователю обратную связь о прогрессе. Я могу внести изменения в пользовательский интерфейс, но пользовательский интерфейс не будет перерисован, поскольку я не могу вернуть указатель инструкций для ОС с помощью await / async.

Есть ли способ обработки сообщений в потоке пользовательского интерфейса без использования async / await. В старые дни Win32 я думаю, что Translate / DispatchMessage можно было бы использовать для поддержания потока сообщений в длительных операциях, и это похоже на то, что мне нужно.

Справочная информация: у меня есть интерфейс, определенный и вызываемый операционной системой Android, который работает в моем потоке пользовательского интерфейса. Важно, чтобы мы возвращали результат этой длительной операции из этого сервиса. Поскольку интерфейс не определен как асинхронный, я не могу использовать await, чтобы позволить IP вернуться в ОС. Если бы я это сделал, функция немедленно вернулась бы (без извлечения результатов) и продолжила бы выполнение (т. Е. Не получилось бы). Я не могу изменить эти обстоятельства.

// The following class is called directly by the AndroidOS
class CloudHostCardService : HostApduService
{
    // The following method is called by the AndroidOS on the UI thread
    public override byte[] ProcessCommandApdu(byte[] commandApdu, Bundle extras)
    {
        ViewModels.MainPageViewModel.SetStatus("Processing Cmd");  // <-- updates UI
        return processor.ProcessCommand(commandApdu); // <-- Long running operation
    }
}

Есть ли другой способ вызвать перерисовку (сообщения насоса в Win32 говорят)?

1 Ответ

0 голосов
/ 04 ноября 2018

HostApduService позволяет возвратить null из ProcessCommandApdu, а затем использовать SendResponseApdu для предоставления ResponseApdu.

Этот метод работает в главном потоке вашего приложения. Если вы не можете вернуть ответный APDU немедленно, верните null и позже используйте метод sendResponseApdu (byte []).

Пример:

public class SampleHostApduService : HostApduService
{
    public override void OnDeactivated([GeneratedEnum] DeactivationReason reason)
    {
    }

    public override byte[] ProcessCommandApdu(byte[] commandApdu, Bundle extras)
    {
        // Update your UI via your viewmodel.

        // Fire and forget
        Task.Run(() => {
            this.SendResponseApdu(processor.ProcessCommand(commandApdu));
         });

        // Return null as we handle this using SendResponseApdu
        return null;
    }
}
...