2014-11-28 3 views
0

Я хочу непрерывно запускать поток. Этот поток будет опросить и проверить статус карты. Вот пример реализации:Использование задачи для непрерывной работы 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 непрерывно. Он не спит вообще на 15 секунд. Что не так с этим кодом?

+2

Не хорошо: 'while (true) {}' Это будет всасывать все тактовые циклы процессора. –

+0

Что вы пытаетесь сделать с этим статусом после опроса? вы хотите опросить, пока он не вернется? –

+0

@SteveWellens. Просто делайте тест здесь. Это пример кода. удалит это из производственного кода. Моя главная задача - получить «chkRequestTask» в цикле в отдельном потоке, как показано в моем примере кода выше – user726720

ответ

3

Вы вызываете chkRequestTask рекурсивно, используя Task.Factory.StartNew, который вам вообще не нужен.

Непонятно, почему вам необходимо опросить статус, лучше всего проверить любое событие или обратный вызов или WaitHandle, предоставленный API-интерфейсом карты, о котором вы говорите. Это должно держать вас подальше от боли.

Если вы считаете, что опрос - это единственный вариант, с которым вы остались, вы можете сделать это следующим образом.

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, где в коде, если можно ждать вызова, если нет, то приложите продолжение или использовать блокирование task.Wait.

await ChkRequestTask(token); 

Этот метод не должен возвращать логическое значение, как вы возвращения из метода только тогда, когда оно является ложным, то можно предположить, статус является false когда Task вернулся из ChkRequestTask Завершает, что означает опрос возвращается false или CancellationToken отменяется, и в этом случае вы получите TaskCanceledException

+0

Спасибо Шрирам, я только что оставил работу. Будете проверять это и возвращаться к вам. Что касается одной из ваших проблем в отношении обратного вызова события или WaitHandle с карты, для меня это был первый приоритет. Но у этой конкретной карты у меня нет этого объекта. Я еще раз подтвердил это с ребятами поддержки. – user726720

+0

Протестировал вашу логику, похоже, работает над той же нитью. Я хочу, чтобы это работало в другом потоке. – user726720

+0

@ user726720 Это неважно. Просто используйте 'Task.Run' Пример:' bool status = wait Task.Выполнить (() => PollTheCardForStatus()); ' –

0

Вот как я это сделал. Кажется, он работает правильно. Поскольку это фоновый поток, он выйдет, когда приложение выйдет. Может ли кто-нибудь посоветовать, если это правильный способ сделать это.

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

Я уже показал вам право путь. –

+0

Спасибо, Шрирам, проверит это и вернется, немного занят здесь – user726720

Смежные вопросы