-2

I have an interface ISFactory as follows.

namespace MyApp.ViewModels
{
    public interface IStreamFactory
    {
        Stream CreateSPStream(string sPName);
    }
}

On Windows non-universal version the above function was implemented as follows.

public Stream CreateSerialPortStream(string serialPortName)
{
    var p = new System.IO.Ports.SerialPort();
    p.PortName = serialPortName;
    p.BaudRate = 9600;
    p.RtsEnable = true;
    p.DtrEnable = true;
    p.ReadTimeout = 150;
    p.Open();
    return p.BaseStream;
}

This implementation is no longer available in Windows Universal. What I attempted is shown below.

public  Stream CreateSerialPortStream(string serialPortName)
{
    var selector = SerialDevice.GetDeviceSelector(serialPortName); //Get the serial port on port '3'
    var devices = await DeviceInformation.FindAllAsync(selector);
    if (devices.Any()) //if the device is found
    {
        var deviceInfo = devices.First();
        var serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
        //Set up serial device according to device specifications:
        //This might differ from device to device
        serialDevice.BaudRate = 19600;
        serialDevice.DataBits = 8;
        serialDevice.Parity = SerialParity.None;
    }
}

I get the following error.

The await operator can only be used within an async method.`

Can anyone suggest a way around this.

Nkosi
  • 235,767
  • 35
  • 427
  • 472
liv2hak
  • 14,472
  • 53
  • 157
  • 270

2 Answers2

10

The best approach is to make the method async, as the compiler error indicates:

public async Task<Stream> CreateSerialPortStreamAsync(string serialPortName)

This will require the interface to change as well:

Task<Stream> CreateSerialPortStreamAsync(string serialPortName);

And yes, all callers of this method will need to be updated.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • What will I return from the function? – liv2hak Sep 11 '16 at 22:29
  • 1
    @liv2hak you just return a `Stream`, which is automatically wrapped in a `Task` – zerkms Sep 11 '16 at 23:05
  • @zerkms - When I add async to the interface function, it says modified async is not valid for this item. – liv2hak Sep 11 '16 at 23:12
  • 1
    @liv2hak `async` keyword is a part of the implementation, not the interface. Just go through the answer once again - it mentions that the signature of the method and of the interface change slightly differently. – zerkms Sep 11 '16 at 23:18
2

1) (Preferable) You can make your method async by changing its sugnature to :

public  async Task<Stream> CreateSerialPortStream(string serialPortName)

each method calling CreateSerialPortStream should be async too. (Also i suggest to rename your method to CreateSerialPortStreamAsync)

2) If you don't want to change your method signature for some reason, you can leave it as is, but use Wait(). In this case, you will lose asynchronous calling.

public  Stream CreateSerialPortStream(string serialPortName)
{
    var selector = SerialDevice.GetDeviceSelector(serialPortName); //Get the serial port on port '3'
    var devicesTask = await DeviceInformation.FindAllAsync(selector);
    devicesTask.Wait();
    var devices = devicesTask.Result;
    if (devices.Any()) //if the device is found
    {
            var deviceInfo = devices.First();
            var serialDeviceTask = SerialDevice.FromIdAsync(deviceInfo.Id);
            serialDeviceTask.Wait();
            var serialDevice = serialDeviceTask.Result;        
            //Set up serial device according to device specifications:
            //This might differ from device to device
            serialDevice.BaudRate = 19600;
            serialDevice.DataBits = 8;
            serialDevice.Parity = SerialParity.None;
      }
}
Maxim Kitsenko
  • 2,042
  • 1
  • 20
  • 43