C#async并在winforms中等待串行通信

时间:2016-09-23 14:26:57

标签: c#

我在这里编写了一个片段,用于异步完成串行数据传输。 VS2015抛出一条消息,表明该方法将同步运行并缺少等待。请告诉我哪里出错了。

    private bool SendRecieveSerialData(string port, byte Cmd, string fileName)
    {
        // bool write_status = ReadWriteSerialData(port, Cmd, fileName);
        bool write_status = SendandReceiveAsync(port,Cmd,fileName).Result;
        if (write_status)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    //private bool ReadWriteSerialData(string port,byte Command, string fileName)

    public bool ReadWriteSerialData(string port,byte Command, string fileName)
    {
        bool comFlag = false;

        if (String.IsNullOrEmpty(port))
        {

            log.WriteErrorLog("Null Port");
            comFlag = false;
            return comFlag;
        }
        else
        {
          //  SerialPortFixer.Execute(port);
            serialPort = new SerialPort(port);

           for (int count = 0; count < BluetoothGlobals.retry_count; count++)
            {


                byte[] text = File.ReadAllBytes(fileName);


                try
                {
                    if (!serialPort.IsOpen)
                    {
                        ConnectedFlag = true;
                        if (fileName != null)
                        {
                            for (int counter = 0; counter < text.Length; counter += 256)
                            {
                                int tempsize = text.Length - counter;

                                if(tempsize > 256)
                                {
                                    tempsize = 256;
                                }

                                Array.Clear(DataFrame, 0, DataFrame.Length);
                                DataFrame[0] = (byte)(MessageFormat.START_FRAME); //Start frame
                                DataFrame[1] = (byte)(tempsize); // Frame Size to be dynamic
                                DataFrame[2] = (byte)(Command & 0xFFu); // LSB
                                DataFrame[3] = (byte)((Command >> 8) & 0xFFu); // MSB
                                Array.Copy(text, counter, DataFrame, 4, tempsize);
                                DataFrame[tempsize + 4] = (byte)(ComputeCheckSum(DataFrame) & 0xFFu);
                                DataFrame[tempsize + 5] = (byte)(((ComputeCheckSum(DataFrame) >> 8) & 0xFFu)); // MSB
                                DataFrame[tempsize + 6] = (byte)(MessageFormat.END_FRAME);


                            }
                        }
                        else
                        {                                    
                            DataFrame[0] = (byte)(MessageFormat.START_FRAME); //Start frame
                            DataFrame[1] = (byte)(MessageFormat.PING_SIZE); // Frame Size to be dynamic
                            DataFrame[2] = (byte)(Command & 0xFFu); // LSB
                            DataFrame[3] = (byte)((Command >> 8) & 0xFFu); // MSB
                            DataFrame[4] = 0; 
                            DataFrame[5] = (byte)(ComputeCheckSum(DataFrame) & 0xFFu);
                            DataFrame[6] = (byte)(((ComputeCheckSum(DataFrame) >> 8) & 0xFFu)); // MSB
                            DataFrame[7] = (byte)(MessageFormat.END_FRAME);
                        }

                        serialPort.Open();
                        serialPort.BaudRate = 115200;
                        serialPort.Parity = Parity.None;
                        serialPort.StopBits = StopBits.One;
                        serialPort.Handshake = Handshake.None;
                        serialPort.DataBits = 8;
                        serialPort.Write(DataFrame, 0, DataFrame.Length);
                        serialPort.DataReceived += new SerialDataReceivedEventHandler(Current_port_DataReceived);
                        comFlag = true;

                         if (comFlag)
                        {

                            break;
                        }

                    }
                }
                catch (Exception e)
                {
                    log.WriteErrorLog(e.Message);
                    continue;
                }
            }

        }

        return comFlag;
    }

    public async Task<bool> SendandReceiveAsync(string portnum,byte cmd, string file)
    {

        bool task_state = await Task.Factory.StartNew(() => ReadWriteSerialData(portnum, cmd, file));

        if (task_state)
            return true;
        else
            return false;
    }

3 个答案:

答案 0 :(得分:3)

methoddeclaration中的关键字async不会使方法异步运行。  只有在使用await关键字声明的方法内使用async调用的方法调用才会异步执行。

例如:

public async Task RunPartsAsync()
{
    using(var someStream = new SomeStream(someSource))
    {
        await someStream.ReadAsync(); //this will be executed asynchronously

        someStream.ReadAsync(); //this will be executed asynchronously but not awaited
                                // => Console.WriteLine might be called/finish before ReadAsync finished

        Console.WriteLine("asdf"); //this will NOT be executed asyncronously
    }
}

答案 1 :(得分:0)

您可以尝试以下操作:

  1. 让您进行方法同步

    public bool ReadWriteSerialData(string port, byte Command, string fileName)
    {
        var comFlag = false;
        // ... your cdode here.....
        return comFlag;
    }
    
  2. 将其作为单独的任务调用

    public async Task<bool> SendandReceiveAsync(string portnum, byte cmd, string file)
    {
    
        bool task_state = await Task.Factory.StartNew(()=>ReadWriteSerialData(portnum, cmd, file));
    
        if (task_state)
            return true;
        else
            return false;
    }
    

答案 2 :(得分:0)

这样做:http://blog.stephencleary.com/2012/02/async-and-await.html

public async Task NewStuffAsync()
{
  // Use await and have fun with the new stuff.
  await ...
}

public Task MyOldTaskParallelLibraryCode()
{
  // Note that this is not an async method, so we can't use await in here.
  ...
}

public async Task ComposeAsync()
{
  // We can await Tasks, regardless of where they come from.
  await NewStuffAsync();
  await MyOldTaskParallelLibraryCode();
}

如果您从事件中调用ComposeAsync

public async void ButtonClick(object sender, System.EventArgs e)  {
  await ComposeAsync; //or
  await Task.Run(() => ComposeNonAsync());
}