我想连续运行一个帖子。该线程将轮询并检查卡状态。以下是一个示例实现:
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秒(通常它应该每50ms检查一次,但出于测试目的,我保持15秒)。
但是在上面的示例中,它并没有在睡觉,它只是让我Checking the card
持续不断。 15秒时,它根本不睡觉。这段代码有什么问题?
答案 0 :(得分:3)
您正在使用您根本不需要的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
。
await ChkRequestTask(token);
此方法不需要返回bool,因为只有当它从false返回时才会返回bool,当false
从{Task
返回时,可以安全地假设状态为ChkRequestTask
1}}完成,这意味着民意调查返回false或CancellationToken
被取消,在这种情况下,您将获得TaskCanceledException
答案 1 :(得分: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();
}