C ++ / CX concurrency :: create_task с функцией DataReader LoadAsync вызывают: «Идентификатор операции недопустим». - PullRequest
0 голосов
/ 23 октября 2019

Я разрабатываю клиентский модуль TCP для Hololens первого поколения с собственным C ++ / CX.

Я создаю пакетный класс, который содержит 1 x (uint32_t) + 7 x (float). Сервер реализован всинхронизированный способ, который передает пакеты клиенту (Hololens) каждый кадр.

Receiver.h

namespace HoloNet {
    public ref class holoATCFrameReceiver sealed
    {
    public:
        holoATCFrameReceiver(
            _In_ Windows::Networking::Sockets::StreamSocket^ streamSocket);

        Windows::Foundation::IAsyncOperation<TrackerFrame^>^ ReceiveAsync();


    private:
        Concurrency::task<TrackerFrame^> ReceiveTrackerFrameAsync();


    private:
        Windows::Networking::Sockets::StreamSocket^ _streamSocket;


        Windows::Storage::Streams::DataReader^      _reader;
        bool                                        _readInProgress;

    };
}

и Receiver.cpp

namespace HoloNet {
    holoATCFrameReceiver::holoATCFrameReceiver(
        Windows::Networking::Sockets::StreamSocket ^ streamSocket)
        : _streamSocket(streamSocket)
    {
        _readInProgress = false;

        // reader
        _reader = ref new Windows::Storage::Streams::DataReader(
            _streamSocket->InputStream);

        _reader->UnicodeEncoding =
            Windows::Storage::Streams::UnicodeEncoding::Utf8;

        _reader->ByteOrder =
            Windows::Storage::Streams::ByteOrder::LittleEndian;
    }

    Windows::Foundation::IAsyncOperation<TrackerFrame^>^ holoATCFrameReceiver::ReceiveAsync()
    {
        return concurrency::create_async(
            [this]()
            {
                return ReceiveTrackerFrameAsync();
            });
    }

    Concurrency::task<TrackerFrame^> 
        holoATCFrameReceiver::ReceiveTrackerFrameAsync()
    {
        return concurrency::create_task(
            _reader->LoadAsync(TrackerFrame::TrackerFrameLength)
        ).then([this](Concurrency::task<unsigned int> headerBytesLoadedTaskResult)
        {
            headerBytesLoadedTaskResult.wait();
            const size_t frameBytesLoaded = headerBytesLoadedTaskResult.get();

            if (TrackerFrame::TrackerFrameLength != frameBytesLoaded)
            {
                throw ref new Platform::FailureException();
            }


            _readInProgress = true;

            TrackerFrame^ header;

            TrackerFrame::Read(
                _reader,
                &header);

            dbg::trace(
                L"SensorFrameReceiver::ReceiveAsync: sensor %i: t( %f, %f %f ), q( %f, %f, %f, %f)",
                header->sensorID,
                header->x,
                header->y,
                header->z,
                header->qw,
                header->qx,
                header->qy,
                header->qz);

            _readInProgress = false;

            return header;
        });
    }

}

Выдает ошибкув * _reader-> LoadAsync (TrackerFrame :: TrackerFrameLength) *

enter image description here

Получатель вызывается в клиентском классе, как показано ниже:

    void holoTcpATCClient::OnReceiveATCframe(TrackerFrame^& header) {
        std::lock_guard<std::mutex> guard(_socketMutex);
        // check read in process
        if (_readInProcess)
        {
            return;
        }

        _readInProcess = true;
        concurrency::create_task(
            _receiver->ReceiveAsync()).then(
                [&](concurrency::task<TrackerFrame^> sensorFrameTask)
        {
            sensorFrameTask.wait();
            TrackerFrame^ sensorFrame = sensorFrameTask.get()
            header =  sensorFrame;
        });
        _readInProcess = false;
    }

_receiver-> ReceiveAsync () - начало ошибки.

Интересно, есть ли способ притворитьсяэто происходит путем внесения некоторых изменений в LoadAsync () DataReader for StreamSocket в режиме параллелизма :: create_task? Заранее большое спасибо за помощь!

...