Сокеты: задержка между получением и отправкой (WriteStream.WriteAsync () и ReadStream.ReadAsync ()) - PullRequest
0 голосов
/ 14 ноября 2018

Как правильно реализовать задержку между отправкой строки с использованием WriteStream.WriteAsync () и ожиданием ответа с использованием ReadStream.ReadAsync () ?

Я использую плагин rda.SocketsForPCL для создания клиентского сокета TCP, а затем соответствующих потоков чтения и записи.

Когда я реализую задержку с помощью TimeSpan.FromMilliseconds (200)), я получаю System.NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта в VS 2017. Я новичок в C # и Xamarin, и я не уверен как реализовать задержку, отличную от описанного выше метода, которая не будет вызывать исключение.

Существует ли «глобальный» обработчик исключений, который может быть каким-то образом реализован для обработки таких исключений, как, например, VS 2017, не нарушает код и не показывает точно, где на самом деле произошло исключение?

Я реализовал приведенную ниже страницу активности в Xamarin.Forms, но она не позволяет мне реализовать задержку с использованием TimeSpan.FromMilliseconds (200)); , который комментируется в функции UpdateUserDataAsync () ниже :

 public InputPage ()
{
    try
    {
        InitializeComponent();
    }
    catch (Exception ex)
    {
        string err = ex.Message;
        throw;
    }

    client = SharedSocket.Instance().getSocket();                   // Get persistent Socket ===> client connection
    UpdateUserDataAsync();                                          // Used to update the contents of the Listview
    loadSampleData();                                               // Load the Items in the ListView   

    BindingContext = this;

    this.BindingContext = new Relays();                             // Binding the Listview items
    var neg = lstView.BindingContext as Relays;
    InputID = neg.ID;
}

private async void UpdateUserDataAsync()                        // Request and Receive Controller Name
{
    byte[] rv = new byte[] { 0x01, 0x01, 0x01 0x01, 0x01, 0x01, 0x01 };    // Request
    Send_CntrP(rv);                                             // Send request
   //await Task.Delay(TimeSpan.FromMilliseconds(200));
rec2 = await ReceiveByte();
}// UpdateUserDataAsync

private void loadSampleData()
{
    ObservableCollection<Relays> lisInputs = new ObservableCollection<Relays>();

    if (rec2.Length >= 4)
    {
        byte[] states = Encoding.ASCII.GetBytes(rec2);      // Create byte array of received string

        for (int j=6; j<22; j++)
        {
            switch (states[j])
            {
                case 0x00:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "ERROR" + (j - 5), State = "ERROR" });
                    break;

                case 0x01:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State= "Toggle"});
                     break;

                case 0x02:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "ON"});
                    break;

                case 0x03:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "OFF"});
                    break;

                case 0x04:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "NO"});
                    break;

                case 0x05:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "NC"});
                    break;

                case 0x10:                                          
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "SC"});
                    break;

                case 0x11:                                         
                  lisInputs.Add(new Relays { ID = j - 5, Name = "IOK" + (j - 5), ImageUrl = "round_on.png", State = "OC"});
                    break;
            }
        }
    }
    else
    {
        for (int i = 0; i < num; i++)
        {
            Images[i] = "round_off.png";
            InputName[i] = "ERROR";
            InputOn[i] = false;
            InputState[i] = "ERROR";

            lisInputs.Add(new Relays { Name = InputName[i] + i, ImageUrl = Images[i], ID = i, State = InputState[i] });
        }
    }

    lstView.ItemsSource = lisInputs;
}

public class MyListItemEventArgs : EventArgs
{
    public Relays MyItem { get; set; }

    public MyListItemEventArgs(Relays item)
    {
        this.MyItem = item;
    }
}

// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// +++++++++++++++++++++++ Sending Messages+++++++++ +++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public async void Send_CntrP(byte[] Comms)
{
    var Len = Comms.Length;                                        // Read the byte array Length

    if (client.Socket.Connected && Len <= 23)                       // No longer than 22 bytes of data to be sent                        
    {
        try
        {
            await client.WriteStream.WriteAsync(Comms, 0, Len);    // Send data of specified Length
            await client.WriteStream.FlushAsync();                           // Make sure all the buffer output data is sent   
            await Task.Delay(TimeSpan.FromMilliseconds(200));      // Delay before next TX to ensure buffer is emptied correctly
        }
        catch (Exception ex)                                       // Exception Handler
        {
            return;
            throw ex;
        }
    }// Client Connected

    else
    {
        XFToast.ShortMessage("Error updating name.\n\rPlease check the connection or length of the entry");   //Android Native Toast Message
    }
}// Send_CntrP 
 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++ Receiving Messages +++++++++++++++++
// +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public async Task<string> ReceiveByte()           // Receive messages Asynchronously
{
    int bytesRec = 0;
    var buffer = new byte[28];

    if (client.Socket.Connected)                  // Check Socket connection
    {      
        while (bytesRec != -1)                    // Read received data ---> byte-by-byte
        {
            try
            {
                bytesRec = await client.ReadStream.ReadAsync(buffer, 0, 28);
            }

            catch (Exception ex)                  // Exception Handler (to prevent App crash)
            {
                XFToast.ShortMessage("Error receiving message.\n\rPlease check the WIFI connection.");
                return "ERROR";                   // Return an "ERROR" message if failed
                throw ex;
            }

            var meh = buffer.ToArray();                              
            rec2 = System.Text.Encoding.UTF8.GetString(meh);         

            if (rec2.Length >= 1 && rec2.Length < 30)                
            {
                return await Task.FromResult(rec2);                  // Return a string 
            }
            else
            {
                //await DisplayAlert("Error", "Error receiving message.", "OK");
                XFToast.ShortMessage("Error receiving message.\n\rPlease verify the connection.");   //Android Native Toast Message
                return "ERROR";         // Return an "ERROR" message
            }
        }// Reading response 
    }// Client
    else
    {
        return err;     // Return a "Connection Error" string when no connection is available
    }

    return rec2;         // Return the received bytes in a string 
}// ReceiveByte
// 
  ++++++++++++++++++++++++++++++++++++++++++++++++
 }

Прошу прощения за длинный пост, но я уже давно борюсь с этой проблемой, и у меня недостаточно опыта, чтобы разбираться со всеми асинхронными методами и поиском исключений, а затем обрабатывать их в VS 2017 и Xamarin как я все еще изучаю основы: (

Заранее благодарю за любую помощь / предложения.

1 Ответ

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

Вот пример кода моего решения

    enum READ_WRITE
    {
        READ,
        WRITE
    }
    public class Test
    {
        private static readonly object readWritelock = new object();
        public static object ReadWrite(READ_WRITE readWrite, object data)
        {
            object returnValue = 0;
            lock (readWritelock)
            {
                switch (readWrite)
                {
                    case READ_WRITE.READ :
                        //add you read code here
                        break;

                    case READ_WRITE.WRITE :
                        //add your write code here
                        break;
                }
            }
            return returnValue;
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...