套接字:接收和发送之间的延迟(WriteStream.WriteAsync() 和 ReadStream.ReadAsync())
Sockets: delay between receive and send (WriteStream.WriteAsync() and ReadStream.ReadAsync())
如何在使用 WriteStream.WriteAsync() 发送字符串和使用 ReadStream.ReadAsync 等待响应之间正确实现延迟()?
我正在使用 rda.SocketsForPCL 插件创建 TCP 客户端套接字,然后创建相应的读写流。
当我使用 TimeSpan.FromMilliseconds(200)) 实现延迟时,我得到一个 System.NullReferenceException: Object reference not set to an instance of an object in VS 2017。我是 C# 的新手并且Xamarin 和我不确定如何实现除上述方法之外的不会导致抛出异常的延迟。
是否有 "Global" 异常处理程序可以以某种方式实现以处理诸如此类的异常,因为 VS 2017 不会破坏代码并向您准确显示异常实际发生的位置?
我在 Xamarin.Forms 中实现了下面的 activity 页面,但它不允许我使用 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
//
++++++++++++++++++++++++++++++++++++++++++++++++
}
很抱歉拖了这么久 post 但我已经为这个问题苦苦挣扎了一段时间,我没有足够的经验来处理所有的异步方法和异常 "finding" 然后使用 VS 2017 和 Xamarin 对其进行处理,因为我仍在学习基础知识:(
提前感谢您的任何 help/suggestions。
这是我的解决方案的示例代码
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;
}
}
如何在使用 WriteStream.WriteAsync() 发送字符串和使用 ReadStream.ReadAsync 等待响应之间正确实现延迟()?
我正在使用 rda.SocketsForPCL 插件创建 TCP 客户端套接字,然后创建相应的读写流。
当我使用 TimeSpan.FromMilliseconds(200)) 实现延迟时,我得到一个 System.NullReferenceException: Object reference not set to an instance of an object in VS 2017。我是 C# 的新手并且Xamarin 和我不确定如何实现除上述方法之外的不会导致抛出异常的延迟。
是否有 "Global" 异常处理程序可以以某种方式实现以处理诸如此类的异常,因为 VS 2017 不会破坏代码并向您准确显示异常实际发生的位置?
我在 Xamarin.Forms 中实现了下面的 activity 页面,但它不允许我使用 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
//
++++++++++++++++++++++++++++++++++++++++++++++++
}
很抱歉拖了这么久 post 但我已经为这个问题苦苦挣扎了一段时间,我没有足够的经验来处理所有的异步方法和异常 "finding" 然后使用 VS 2017 和 Xamarin 对其进行处理,因为我仍在学习基础知识:(
提前感谢您的任何 help/suggestions。
这是我的解决方案的示例代码
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;
}
}