Как работать с async / await в совместно используемой кодовой базе на платформе, которая его не поддерживает - PullRequest
2 голосов
/ 21 июня 2019

Как поддерживать кодовую базу совместно используемой библиотеки C #, которая может, но не обязательно, использовать логику асинхронного / ожидающего выполнения в зависимости от платформы назначения.

Я создаю библиотеку .NET Standard, которая будет выполнять некоторые бизнес-задачи, связанные с асинхронной логикой (вызовы http). Сейчас я ищу решение, чтобы иметь одну кодовую базу и разделить ее между:

  • Xamarin.Forms (Android, возможно UWP)
  • .NET Framework (WinForms)
  • .NET CompactFramework (WinForms).

Проблема находится в последней среде, которая вообще не поддерживает async / await. Прямо сейчас я перекомпилирую библиотечный код в проекте VS2008 с файлами, добавленными в виде ссылок. Но код результата не легко поддерживать, потому что он основан на препроцессоре. Используя директиву #if, я могу включать и отключать части кода async / await и подготавливать код для компиляции.

Есть ли другое решение для упрощения такого многоплатформенного кода?

using System;
using System.Collections.Generic;
using System.Text;

#if ASYNC
using System.Threading.Tasks;
#endif

namespace SharedLibTest
{
    public interface IDbEventSource
    {
#if ASYNC      
        Task<DbEventResult> ExecuteSource(EventContext ctx);
#else
        DbEventResult ExecuteSource(EventContext ctx);
#endif
    }

    interface IEventStep
    {
#if ASYNC
        Task Execute(EventContext ctx);
#else
        void Execute(EventContext ctx);
#endif
    }

    class EventStepDb : IEventStep
    {
        private readonly IDbEventSource _dbsrc;

        public EventStepDb(IDbEventSource dbsrc)
        {
            this._dbsrc = dbsrc;
        }

#if ASYNC
        public async Task Execute(EventContext ctx)
#else
        public void Execute(EventContext ctx)
#endif
        {
            #if ASYNC
                        DbEventResult res = await _dbsrc.ExecuteSource(ctx);
            #else
                        DbEventResult res = _dbsrc.ExecuteSource(ctx);
            #endif

            ctx.State = res.Answer;
        }
    }
}

...