0

I want to execute my SetupSerialPort method every 4 seconds.

After doing some research, I think I need to be using Timers. But it seems the timer method is giving me an error message (+ highlighted in comment:

Argument 1 : can't convert from "method group" to "Timer Callback"

internal class GetPortTetheredHelper
    {
        private static int second;
        public static void RunTimer()
        {
            second = 4 * 1000;

            var timer = new Timer(SetupSerialPort, null, 0, second);
            // Argument 1 : can't convert from "method group" to "Timer Callback"
        }

        public static void SetupSerialPort(SerialPort sp)
        {
            sp.PortName = PortCom();
            sp.BaudRate = 57600;
            sp.DataBits = 8;
            sp.StopBits = StopBits.One;
            sp.Parity = Parity.None;

            sp.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
            sp.Open();
        }

        private static string PortCom()
        {
            string[] ports = SerialPort.GetPortNames();
            return ports[0];
        }

        private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;

            if (sp.IsOpen)
            {
                sp.ReadLine();
            }
        }
    }
Ermiya Eskandary
  • 15,323
  • 3
  • 31
  • 44
Wavesolid
  • 175
  • 11
  • Where do you expect a `SerialPort` to be created to be passed into your `SetupSerialPort` method? (You haven't included any `using` directives, so we can't tell which `Timer` class you mean, which makes it harder to help you with the rest, too. I suspect it's System.Threading.Timers though.) – Jon Skeet Oct 03 '21 at 07:48
  • Note that for `SetupSerialPort` to be convertible to a `TimerCallback`, it would need a signature of `void SetupSerialPort(object state)` or `void SetupSerialPort(object? state)` if you're using nullable reference types. – Jon Skeet Oct 03 '21 at 07:50
  • @JonSkeet i'm sorry i mean my `SetupSerialPort` method not `SerialPort` and this `Timer` class i've been using `System.Threading;` – Wavesolid Oct 03 '21 at 07:51
  • @JonSkeet can you give me a clear example? i did with `object state` inside my parameter of `SetupSerialPort` method, but the TimerCallback still can't convert that method – Wavesolid Oct 03 '21 at 07:56
  • 1
    It really should do - if you change your declaration to `public static void SetupSerialPort(object state)`, the `Timer` constructor will compile. (I've just tried it.) But you'll need to declare `sp` within your method instead, and create a new `SerialPort` there. – Jon Skeet Oct 03 '21 at 07:58
  • why you open serial port every 4 second ? – behroozbc Oct 03 '21 at 08:01
  • Relevant: https://stackoverflow.com/a/14011893 – rene Oct 03 '21 at 08:02
  • @JonSkeet ah you right, i tried to removing `sp` from the parameters now the `Timer` constructor didn't give me an error message. So the problem comes from my `sp`, but can you give me an explanation why `sp` made my method can't convertable to `TimerCallback`? I really appreciate that. – Wavesolid Oct 03 '21 at 08:02
  • @behroozbc simply, because i have a task to Read the data from a specific port for every 4 seconds – Wavesolid Oct 03 '21 at 08:03
  • Because you can only convert a method group to a compatible delegate - and a delegate with a parameter of `object` isn't compatible with a method that has a parameter of `SerialPort`. Suppose you'd passed in "this isn't a serial port" (a string) as the start to the timer - what would you expect to happen? – Jon Skeet Oct 03 '21 at 08:04
  • 1
    @Wavesolid: *Reading* data from a serial port every 4 seconds isn't the same as *opening* it every 4 seconds. I suspect you may be better opening it once, then calling `ReadExisting` every 4 seconds instead. – Jon Skeet Oct 03 '21 at 08:05
  • @JonSkeet you right, it much better to `ReadExisting` for every 4 secs instead `open` the port for every 4 secs. I take your suggest and continuing my research to do that. Really much thanks. – Wavesolid Oct 03 '21 at 08:10
  • @Wavesolid you can first time open port and read every 4 seconds – behroozbc Oct 03 '21 at 08:24

1 Answers1

0

I change code and close port every after read

internal class GetPortTetheredHelper
    {
        private static int second;
        private static SerialPort sp;
        public static void RunTimer()
        {
            second = 4 * 1000;
            sp = new SerialPort();
            var timer = new Timer(SetupSerialPort, null, 0, second);
        }

        public static void SetupSerialPort()
        {
            sp.PortName = PortCom();
            sp.BaudRate = 57600;
            sp.DataBits = 8;
            sp.StopBits = StopBits.One;
            sp.Parity = Parity.None;
            sp.Open();
            // this code need more check to sp is opened
            if (sp.IsOpen)
            {
                var serailData= sp.ReadLine();
                sp.Close();
            }
            
        }

        private static string PortCom()
        {
            string[] ports = SerialPort.GetPortNames();
            return ports[0];
        }

        
    }
behroozbc
  • 1,992
  • 2
  • 12
  • 25