abduls85
abduls85

Reputation: 548

Question on threading in C#

I have a Windows Forms application at the moment, and I want to create a new thread and run a method on another class that accepts an input.

For example

public partial class Form1: Form {
    SerialPort serialInput;
    // I want to create a new thread that will pass the parameter serialInput into the method
    // SMSListener on another class and run the method contionously on the background.
}

class SMS
{
    public void SMSListener(SerialPort serial1)
    {
        serial1.DataReceived += port_DataRecieved;
    }

    private void port_DataRecieved(object sender, SerialDataReceivedEventArgs e)
    {
        // Other codes
    }
}

How do I perform this in C#? I have seen numerous examples on the web, and most of them run the method on the same class with no parameters, but none that suits my requirements.

Upvotes: 2

Views: 290

Answers (3)

Nikhil
Nikhil

Reputation: 3384

I am not an expert on Multithreading but to the best of my knowledge you can only start threads on methods that accept an object parameter and return void. So in order to achieve that for your problem (don't shoot me down if there is a better approach!) I would do something like

public partial class Form1: Form {
    SerialPort serialInput;
    // I want to create a new thread that will pass the parameter serialInput into the method
    // SMSListener on another class and run the method contionously on the background.
    SMS sms = new SMS();
    Thread t = new Thread(sms.SMSListenerUntyped);
    t.Start(serialInput);
}

class SMS
{
    public void SMSListenerUntyped(object serial1) {
        if (serial1 is SerialPort) //Check if the parameter is correctly typed.
             this.SMSListener(serial1 as SerialPort);
        else
           throw new ArgumentException();
    }

    public void SMSListener(SerialPort serial1)
    {
        serial1.DataReceived += port_DataRecieved;
    }

    private void port_DataRecieved(object sender, SerialDataReceivedEventArgs e)
    {
        // Other code.
    }

Upvotes: 2

Polity
Polity

Reputation: 15130

How about just use the ThreadPool directly with a anonymous method allowing you to access your surrounding locals?

    public void OnButtonClick(object sender, EventArgs e)
    {
        SerialPort serialInput = this.SerialInput;
        System.Threading.ThreadPool.QueueUserWorkItem(delegate
        {
            SmsListener listener = new SmsListener(serialInput);
        });
    }

Upvotes: 0

Jakob Möllås
Jakob Möllås

Reputation: 4369

Perhaps a Background Worker could help you?
It is a bit hard to understand what you are aiming at.

public class Runner
{
    private readonly BackgroundWorker _worker = new BackgroundWorker();

    public Runner()
    {
        _worker.DoWork += WorkerDoWork;
    }

    public void RunMe(int payload)
    {
        _worker.RunWorkerAsync(payload);
    }

    static void WorkerDoWork(object sender, DoWorkEventArgs e)
    {
        var worker = sender as BackgroundWorker;

        while (true)
        {
            if (worker.CancellationPending)
            {
                e.Cancel = true;
                break;
            }

            // Work
            System.Threading.Thread.Sleep((int)e.Argument);
        }
    }
}

Upvotes: 4

Related Questions