我正在从Public Sub Application_ItemSend(ByVal thisItem As Object, Cancel As Boolean)
Dim ns As Outlook.NameSpace
Dim olfolder As MAPIFolder
Dim Item As Object
Set olApp = CreateObject("Outlook.Application")
Set olNs = olApp.GetNamespace("MAPI")
Set firstFolder = olNs.Folders("test@dk.com") ' name of my shared inbox
Set olfolder = firstFolder.Folders("sent items")
' iterate thru emails
For Each Item In olfolder.Items
' check subject content & date difference
If InStr(Item.Subject, thisItem.Recipients) And DateDiff("m", Item.SentOn, Now) < 1 Then
' added this part
If MsgBox("already sent", vbYesNo + vbQuestion + vbMsgBoxSetForeground, "Message Text Warning") = vbNo Then
' cancel the email
Cancel = True
End If
Exit For
End If
文件中读取字节数据,并将整个字节数据拆分为.bin
字节帧,所以我想一个接一个的16字节帧,然后等到第一个帧结束其循环
SerialPort类的回调方法:
16-16
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
// Read data from serial port:
byte[] buffer = new byte[serialPort.BytesToRead];
serialPort.Read(buffer, 0, buffer.Length);
StringBuilder sb = new StringBuilder();
List<string> response = new List<string>();
for (int i = 0; i < buffer.Length; i++)
{
string currentByte = string.Format("{0:X2}", buffer[i]);
response.Add(currentByte);
sb.AppendFormat("{0:X2}", buffer[i]);
}
string responesCode = response[1].ToString();
if (responesCode == "44")
{
// Wait until the first response is not received
foreach (var packet in packetList.Skip(1))
{
// This method which sending the the data
this.ReadByteDataFromFile(packet);
}
}
}
按钮单击:
FdBrowseFile_Click
ReadByteDataFromFile方法:
private void FdBrowseFile_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
byte[] fileBytes = File.ReadAllBytes(filename);
foreach (byte[] copySlice in fileBytes.Slices(16))
{
var splitedByteArray = copySlice;
if (splitedByteArray.Length != 16)
{
byte[] padd = new byte[16];
var startAt = 0;
Array.Copy(splitedByteArray, 0, padd, startAt, splitedByteArray.Length);
packetList.Add(padd);
}
else
{
packetList.Add(splitedByteArray);
}
}
ReadByteDataFromFile(packetList[0]);
}
}
如何为public void ReadByteDataFromFile(byte[] packet) {
try {
byte[] mBuffer = new byte[24];
byte[] payload = new byte[16];
int i = 0;
foreach(var bytes in packet) {
payload[i++] = bytes;
}
CheckSumHelper checkSumHelper = new CheckSumHelper();
var ckSum = checkSumHelper.GetCheckSum(payload);
mBuffer[0] = 0x02;
mBuffer[1] = 0x10;
mBuffer[2] = CheckSumHelper.GetBytesFromDecimal(packet[0]);
mBuffer[3] = CheckSumHelper.GetBytesFromDecimal(packet[1]);
mBuffer[4] = CheckSumHelper.GetBytesFromDecimal(packet[2]);
mBuffer[5] = CheckSumHelper.GetBytesFromDecimal(packet[3]);
mBuffer[6] = CheckSumHelper.GetBytesFromDecimal(packet[4]);
mBuffer[7] = CheckSumHelper.GetBytesFromDecimal(packet[5]);
mBuffer[8] = CheckSumHelper.GetBytesFromDecimal(packet[6]);
mBuffer[9] = CheckSumHelper.GetBytesFromDecimal(packet[7]);
mBuffer[10] = CheckSumHelper.GetBytesFromDecimal(packet[8]);
mBuffer[11] = CheckSumHelper.GetBytesFromDecimal(packet[9]);
mBuffer[12] = CheckSumHelper.GetBytesFromDecimal(packet[10]);
mBuffer[13] = CheckSumHelper.GetBytesFromDecimal(packet[11]);
mBuffer[14] = CheckSumHelper.GetBytesFromDecimal(packet[12]);
mBuffer[15] = CheckSumHelper.GetBytesFromDecimal(packet[13]);
mBuffer[16] = CheckSumHelper.GetBytesFromDecimal(packet[14]);
mBuffer[17] = CheckSumHelper.GetBytesFromDecimal(packet[15]);
mBuffer[18] = 0x17;
mBuffer[19] = 0x00;
mBuffer[20] = 0x00;
mBuffer[21] = 0x00;
mBuffer[22] = Convert.ToByte(int.Parse(ckSum, System.Globalization.NumberStyles.HexNumber));
mBuffer[23] = 0x03;
serialPort.Write(mBuffer, 0, mBuffer.Length);
} catch (Exception ex) {
ExceptionHandler exceptionHandler = new ExceptionHandler();
exceptionHandler.HandleException(ex);
}
}
方法添加延迟?
答案 0 :(得分:1)
写完第一帧后,循环等待完整响应。
// Set read timeout to value recommended in the communication protocol specification
// so serial port operations don't stuck.
_port.WriteTimeout = 200;
_port.ReadTimeout = 200;
public void OnClick()
{
// Write first frame.
_port.Write(...);
// Now wait for the full response.
// Expected response length. Look for the constant value from the device communication
// protocol specification or extract from the response header (first response bytes) if
// there is any specified in the protocol.
int count = ...;
var buffer = new byte[count];
var offset = 0;
while (count > 0)
{
var readCount = _port.Read(buffer, offset, count);
offset += readCount;
count -= readCount;
}
// Now buffer contains full response or TimeoutException instance is thrown by SerialPort.
// Check response status code and write other frames.
}
为了不阻止UI线程,您很可能仍需要使用同步API和Task.Run()
。请参见关于StackOverflow的C# await event and timeout in serial port communication讨论。
有关更多信息,请查看Kim Hamilton的Top 5 SerialPort Tips文章。
答案 1 :(得分:1)
您需要的是一种阻止某些代码执行的方法,直到发生其他事情为止,或者-如何使事情在两个线程上同步运行。
.NET在System.Threading
命名空间中有很多类用于同步。我们将在此处使用AutoResetEvent
。
将AutoResetEvent
视为旋转门。
如果另一边的人停下来,您将无法前进。
继续前进时,您拨打Wait
-它阻止您前进,
直到有人致电Set
。
现在,如果我们将其应用于我们的问题:
我们需要停止发送数据,直到获得可接受的响应。
因此,在发送数据时调用Wait
,然后让响应处理代码调用Set
使其前进。
这是一个模拟调制解调器的示例。
您发送一些AT命令,它会响应,但是响应始终以\r\n
结尾。
var port = new SerialPort("COM2");
port.Open();
var mre = new AutoResetEvent(false);
var buffer = new StringBuilder();
port.DataReceived += (s, e) =>
{
buffer.Append(port.ReadExisting());
if (buffer.ToString().IndexOf("\r\n") >= 0)
{
Console.WriteLine("Got response: {0}", buffer);
mre.Set(); //allow loop to continue
buffer.Clear();
}
};
var commandsToSend = new string[] { "AT", "AT", "AT+CSQ" };
var responseTimeout = TimeSpan.FromSeconds(10);
foreach (var command in commandsToSend)
{
try
{
Console.WriteLine("Write '{0}' to {1}", command, port.PortName);
port.WriteLine(command);
Console.WriteLine("Waiting for response...");
//this is where we block
if (!mre.WaitOne(responseTimeout))
{
Console.WriteLine("Did not receive response");
//do something
}
}
catch (TimeoutException)
{
Console.WriteLine("Write took longer than expected");
}
catch
{
Console.WriteLine("Failed to write to port");
}
}
Console.ReadLine();
通过虚拟串行端口测试时的样本输出:
(我只回复OK<CR><LF>
)
Write 'AT' to COM2
Waiting for response...
Got response: OK
Write 'AT' to COM2
Waiting for response...
Got response: OK
Write 'AT+CSQ' to COM2
Waiting for response...
Did not receive response