当数据到达我的串行端口将是异步的时,如何通过 web 服务存储数据?

How to store data through web service when data coming to my serial port will be asynchronous?

我有一个设备 "installed" 在用户的桌子上(一张桌子不过是一把椅子或 table 用户将坐在上面),我将支持数千张桌子。

用户将拥有一个 "chip" 并且用户将在安装在其桌面上的设备上扫描此芯片。

该设备将从芯片读取数据并将其发送到我的笔记本电脑,该笔记本电脑也将安装其中一个设备,但该设备是负责收集所有用户扫描芯片数据的主要设备。

所有数据都将通过 wifi 路由器路由到我的设备,我将从我的主设备收听这些数据,并通过串行端口连接从我的笔记本电脑读取该设备的数据。

此数据发送将在每个用户号码扫描 his/her 芯片时发生。

我已经创建了一个 windows 表单应用程序,它会在我的笔记本电脑的后台持续 运行,并且会监听连接主设备的串行端口。

这是我从这里获取的代码:Source Code Reference:

public partial class MainUI : Form
    {
        SerialPortManager _spManager;
        public MainUI()
        {
            InitializeComponent();
            UserInitialization();
        }
   }

    private void UserInitialization()
        {
            _spManager = new SerialPortManager();
            _spManager.NewSerialDataRecieved += new EventHandler<SerialDataEventArgs>(_spManager_NewSerialDataRecieved);
            this.FormClosing += new FormClosingEventHandler(MainUI_FormClosing);
        }

  private void MainUI_Load(object sender, EventArgs e)
        {
           _spManager.StartListening()
        }

 void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int dataLength = _serialPort.BytesToRead;
            byte[] data = new byte[dataLength];
            int nbrDataRead = _serialPort.Read(data, 0, dataLength);
            if (nbrDataRead == 0)
                return;

            // Send data to whom ever interested
            if (NewSerialDataRecieved != null)
            {
                NewSerialDataRecieved(this, new SerialDataEventArgs(data));
            }
        }

  void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)
        {
            if (this.InvokeRequired)
            {
                // Using this.Invoke causes deadlock when closing serial port, and BeginInvoke is good practice anyway.
                this.BeginInvoke(new EventHandler<SerialDataEventArgs>(_spManager_NewSerialDataRecieved), new object[] { sender, e });
                return;
            }
            //data is converted to text
            string str = Encoding.ASCII.GetString(e.Data);

            if (!string.IsNullOrEmpty(str))
            {
                  //Here i will store that data in to my database through web service.
                  //What i should use whether WCF service or Web Api because data will be continuos like at a
                  //time more than 10 or 100 user can scan data at the same time so this event will be fired continuously.
                  //I am using entity framework to store data in to my database and how to ansynchornously call web service to store my data
              //so that my call doesnt block incoming data to serial port
            }
        }

我主要担心的是我会有很多用户同时扫描数据,当超过 10 或 100 个用户同时扫描数据时我将如何处理。

我该如何缓解这个潜在问题?

关闭您的串口并每隔一段时间加载一次。之后一段时间打开端口并扫描所有设备,然后再次关闭。

        public void MainUI.Load(Object sender, Eventargs e)
        {
            if (_spmanager != null && !_spManager.IsOpen)
                //*write the code here where it opens and starts listening
                _spmanager.StartListening();
                //*write the code here where it waits a little bit then 
                _spmanager.Close();
 }

因此,每次加载时,它都会在端口关闭时启动,它会打开一点点,扫描任何值为真,然后再次关闭。

我对此不是很确定,但这只是关于如何处理它的一个想法。代码可能不准确或不正确,我只是快速编写了它。借鉴这个

好的,如果我答对了你需要做这样的事情...

  void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int dataLength = _serialPort.BytesToRead;
            byte[] data = new byte[dataLength];
            int nbrDataRead = _serialPort.Read(data, 0, dataLength);
            if (nbrDataRead == 0)
                return;

            // Send data to api
            string str = Encoding.ASCII.GetString(e.Data);
                if (!string.IsNullOrEmpty(str))
                {
                      var api = new HttpClient();
                      api.BaseUrl("http://somewhere.com");
                      api.PostAsJsonAsync("api/Something", str)
                }

            if (this.InvokeRequired)
            {
                // Using this.Invoke causes deadlock when closing serial port,
                // and BeginInvoke is good practice anyway.
                this.BeginInvoke(new EventHandler<SerialDataEventArgs>(
                    _spManager_NewSerialDataRecieved), new object[] { sender, e
                });
                return;
            }
        }


// i think this can go completely ...
void _spManager_NewSerialDataRecieved(object sender, SerialDataEventArgs e)

post将数据发送到 webapi,但是当 post 发生在另一个线程上时,串口可以继续接收数据