. NET WebAPI - ответ от метода обратного вызова SDK - PullRequest
0 голосов
/ 12 марта 2020

Уже довольно давно я пытаюсь найти решение, но я застрял на несколько дней. Буду очень признателен за любую помощь.

Я работаю над SDK сканера отпечатков пальцев и пытаюсь написать на нем Windows Service Self-Hosted WebAPI, чтобы его можно было использовать из Интернета.

Итак, у меня есть контроллер WebAPI, где у меня есть этот метод ниже, который будет вызываться из Web App.

public async Task<IHttpActionResult> Enroll()
        {
            using (FM220 fp = new FM220())
            {
                await Task.Factory.StartNew(() =>
                {
                    fp.Initialize();
                    fp.Capture();

                    //How to get the Fingerprint data from ScanCompleteFM220()?

                    fp.Dispose();
                });

            }

            return Ok();
        }

Проблема в том, что Capture() метод на самом деле является void методом, потому что он не ничего не возвращает. Вот подпись для Capture()

internal class FM220 : FM220_Scanner_Interface, IDisposable
{
    private FM220_SDK_Main sdk;
    private bool connected = false;

    public void Initialize()
    {
        sdk = new FM220_SDK_Main(this);
        FM220_Init_Result result = sdk.initFM220Scanner();

        if (result.getResult())
        {
            connected = true;
        }
    }

    public void Dispose()
    {
        sdk.unInitFM220();
        connected = false;
    }

    public void Capture()
    {
        if (connected)
        {
            //IntPtr refpntr = IntPtr.Zero;
            //sdk.CaptureFM220(ref refpntr);
            sdk.CaptureThreadProc();
        }
    }

    public void ScanCompleteFM220(FM220_Capture_Result result)
    {
        string fingerTemplate = string.Empty;
        string fingerQuality = string.Empty;
        string error = string.Empty;

        bool isCaptured = result.getResult();

        if (isCaptured)
        {
            fingerTemplate = Convert.ToBase64String(result.getISO_Template());
            fingerQuality = result.getNFIQ().ToString();
        }
        else
        {
            error = result.getError();
        }
    }

    public bool MatchTemplate(ref byte[] fingerTemplate1, ref byte[] fingerTemplate2)
    {
        int[] score = sdk.matchFingerTamplates(ref fingerTemplate1, ref fingerTemplate2);
        if (score[0] == -1)
        {
            return false;
        }
        else
        {
            return true;
        }
    }

    public void ScannerProgressFM220(bool DisplayText, string statusMessage)
    {

    }
}

Как видите, CaptureFM220 или CaptureThreadProc() в Capture() ничего не возвращает. Вместо этого реализованный метод ScanCompleteFM220(FM220_Capture_Result result) вызывается сам по себе, как только снят отпечаток пальца.

Итак, как вы можете видеть, я не могу вызвать ScanCompleteFM220 из Enroll(). Вместо этого мне нужен способ позвонить Enroll() с ScanCompleteFM220. И вот тут я застрял и запутался.

Теперь что касается WebAPI, если я правильно понимаю, у меня есть 2 способа решить эту проблему

  1. Сделать запрос подождите Enroll() (что все равно будет ждать, если я не верну ответ), пока не получу ответ от ScanCompleteFM220 и отправлю результат. Но как? Потому что ScanCompleteFM220 вызывается системой автоматически. Итак, как мне захватить ответ?

  2. Вместо того, чтобы сдерживать запрос, я могу взять функцию обратного вызова на Enroll() и вызвать ее, как только получу ответ от ScanCompleteFM220. Но опять же как?

Обратите внимание, что FM220 реализует FM220_Scanner_Interface, поэтому public void ScanCompleteFM220(FM220_Capture_Result result) - это метод, который я должен реализовать, чтобы получить результат. И я не могу изменить сигнатуру метода.

...