繁体   English   中英

使用Task运行连续线程

[英]Using Task to run continuous Thread

我想连续运行一个线程。 该线程将轮询并检查卡状态。 这是一个示例实现:

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;

    }

我要在这里实现的是chkRequestTask应该在单独的线程上运行。 这将连续轮询卡的状态。 对于此示例,我只是在做: Console.WriteLine("Checking the card");

一旦检查了卡的状态,就应仅针对此样本休眠15秒(通常应每50毫秒检查一次,但出于测试目的,我保留了15秒)。

但是在上面的示例中,它不是在睡觉,而只是在给我连续Checking the card 整整十五秒都没有睡觉。 此代码有什么问题?

你打电话chkRequestTask递归使用Task.Factory.StartNew ,你并不需要在所有。

目前尚不清楚为什么需要轮询状态,更好的主意是检查所讨论的卡API提供的任何事件或回调或WaitHandle 那应该使您摆脱痛苦。

如果您完全相信轮询是剩下的唯一选择,则可以按照以下步骤进行。

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
    }
}

在代码中的其他地方,如果可能的话,等待调用;如果没有,则附加一个继续task.Wait或使用阻塞task.Wait

await ChkRequestTask(token);

此方法不需要返回布尔值,因为仅当它为false时才从该方法返回,因此可以安全地假设从ChkRequestTask返回的Task完成时状态为false ,这意味着poll返回false或CancellationToken被取消。 ,在这种情况下,您将获得TaskCanceledException

这就是我这样做的方式。 它似乎工作正常。 由于它是后台线程,因此在应用程序退出时会退出。 有人可以建议这样做是否正确。

 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();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM