public List <byte> ExchangeData(T msgToWrite, TimeSpan timeout, TaskCompletionTest readyTest)
        {
            // Debug.WriteLine("-------------------------------------------------");
            // prepare task
            var tcs = PrepareTask();

            _proto.BogusReceived += OnDataReceived;

            // write the message
            _proto.BogusOnly();
            _proto.ClearBogus();
            _proto.Write(msgToWrite);

            // wait for eventual replies
            var response = WaitForTaskCompletion(tcs, timeout, readyTest);

            _proto.EndBogusOnly();

            _proto.BogusReceived -= OnDataReceived;

            return(response);
        }
        public List <byte> WaitForTaskCompletion(TaskCompletionSource <DataReceivedEventArgs> tcs, TimeSpan timeout, TaskCompletionTest test)
        {
            // wait for eventual replies
            var sw       = Stopwatch.StartNew();
            var response = new List <byte>();

            while (true)
            {
                bool taskSuccess = tcs.Task.Wait(timeout);
                if (!taskSuccess && sw.Elapsed >= timeout)
                {
                    break;
                }

                if (taskSuccess)
                {
                    response.AddRange(tcs.Task.Result.Data);
                }

                // test if we have all data we wanted (or any other test completion encoded in "test");
                if (test(response))
                {
                    break;
                }

                // we need more data, refresh task
                tcs = PrepareTask();
            }

            _logger.Trace("Task ran to completion; response: {0}", Util.ByteArrayToHexString(response));

            // signal the waiting receiver thread: it waits for us to
            // decide whether or not we want more data
            lock (_receivedTaskLock) {
                _dataReceivedTask = null; // if it failed, make sure task isn't completed again
            }

            _dataReceivedTaskRefresher.Set();

            return(response);
        }
Пример #3
0
 public static Func <List <byte>, bool> CombineLogicalOr(TaskCompletionTest test1, TaskCompletionTest test2)
 {
     return(rcvd => test1(rcvd) || test2(rcvd));
 }