user726720
user726720

Reputation: 1237

Using Task to run continuous Thread

I want run a thread continuously. This thread would poll and check for card status. Here is a sample implementation:

static void Main(string[] args)
        {
           var _cancelationTokenSource = new CancellationTokenSource();
           new Task(() => chkRequestTask(_cancelationTokenSource), _cancelationTokenSource.Token, TaskCreationOptions.LongRunning).Start();

           while (true)
           {
           }

        }

static bool chkRequestTask(CancellationTokenSource _cancellationTokenSource)
    {
        bool noRequest = false;

        while (!_cancellationTokenSource.Token.IsCancellationRequested)
        {
            var RequestTask = Task.Factory.StartNew(() => noRequest = chkRequestTask(_cancellationTokenSource), _cancellationTokenSource.Token);

            if (noRequest)
            {
                _cancellationTokenSource.Token.WaitHandle.WaitOne(15000);
                Console.WriteLine("Waiting for 15Seconds");

            }

            else
            {
                Console.WriteLine("Checking the card");
            }



        }

        return noRequest;

    }

What I want to achieve here is chkRequestTask should be run on a separate thread. This would continously poll the status of the card. For this sample I'm simply doing : Console.WriteLine("Checking the card");.

Once it checks the status of the card it should sleep for 15secs for this sample only (in general it should check every 50ms, but for testing purposes I have kept 15secs).

But in the above sample it's not sleeping it's simply giving me Checking the card continuously. It's not sleeping at all for 15secs. What is wrong with this code ?

Upvotes: 0

Views: 3164

Answers (2)

user726720
user726720

Reputation: 1237

This is how I have done this. It seems to be working properly. As it's a background thread it would exit when the application exits. Could someone advise If this is the right way to do it.

 private void Form1_Load(object sender, EventArgs e)
    {
        m_dev = DASK.Register_Card(DASK.PCI_7250, 0);
        if (m_dev < 0)
        {
            MessageBox.Show("Register_Card error!");

        }

        FunctionToCall();

   }

private void FunctionToCall()
     {


        short ret;
        uint int_value;
        var thread = new Thread(() =>
            {
                while (true)
                {
                    ret = DASK.DI_ReadPort((ushort)m_dev, 0, out int_value);
                    if (ret < 0)
                    {
                        MessageBox.Show("D2K_DI_ReadPort error!");
                        return;
                    }
                    if (int_value > 0)
                   {
                       textBox2.Invoke(new UpdateText(DisplayText), Convert.ToInt32(int_value));

                    }

                    Thread.Sleep(500);
                }
            });
        thread.Start();
        thread.IsBackground = true;
    }

    private void DisplayText(int i)
    {

        textBox2.Text = i.ToString();
    }

Upvotes: 0

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73442

You're calling chkRequestTask recursively using Task.Factory.StartNew which you don't need at all.

It's not clear why you need to poll the status, better idea is to check any event or callback or WaitHandle provided by the card API you're talking about. That should keep you away from the pain.

If at all you believe polling is the only option you've left with, you can do it as follows.

static async Task ChkRequestTask(CancellationToken token)
{
    while (true)
    {
        token.ThrowIfCancellationRequested();

        Console.WriteLine("Checking the card");
        bool status = PollTheCardForStatus();
        if(!status)
            break;

        await Task.Delay(15 * 1000, token);//Adjust the delay as you wish
    }
}

Else where in code, if possible await the call, If not then attach a continuation or use blocking task.Wait.

await ChkRequestTask(token);

This method doesn't need to return bool as you're returning from the method only when it is false, it is safe to assume the status is false when the Task returned from ChkRequestTask completes, which means poll returned false or the CancellationToken is cancelled, in which case you'll get TaskCanceledException

Upvotes: 3

Related Questions