如何创建一个线程/任务有一个连续的循环? [英] How to create a thread/Task with a continuous loop?

查看:180
本文介绍了如何创建一个线程/任务有一个连续的循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要寻找正确的方法/结构,创建一个线程/任务 ...

I am looking for the correct way/structure to create a loop in a Thread/Task...

这样做的原因是,我需要检查数据库每隔15秒对报告的要求。

The reason for this is, i need to check the DB every 15sec for report requests.

这是我试过到目前为止,但我得到 OutOfMemoryException异常

This is what i tried so far, but i get OutOfMemoryException:

    private void ViewBase_Loaded(object sender, RoutedEventArgs e)
{
    //On my main view loaded start thread to check report requests.
    Task.Factory.StartNew(() => CreateAndStartReportRequestTask());
}

private void CreateAndStartReportRequestTask()
{
    bool noRequest = false;

    do
    {
         //Starting thread to Check Report Requests And Generate Reports
         //Also need the ability to Wait/Sleep when there are noRequest.
         reportRequestTask = Task.Factory.StartNew(() => noRequest = CheckReportRequestsAndGenerateReports());

         if (noRequest)
         {
             //Sleep 15sec
             reportRequestTask.Wait(15000);
             reportRequestTask = null;
         }
         else
         {
             if (reportRequestTask.IsCompleted)
             {
                 reportRequestTask = null;
             }
             else
             {
                 //Don't want the loop to continue until the first request is done
                 //Reason for this is, losts of new threads being create in CheckReportRequestsAndGenerateReports()
                 //Looping until first request is done.
                 do
                 {

                 } while (!reportRequestTask.IsCompleted);

                 reportRequestTask = null;
             }
         }

    } while (true);
}

private bool CheckReportRequestsAndGenerateReports()
{
    var possibleReportRequest = //Some linq query to check for new requests

    if (possibleReportRequest != null)
    {
        //Processing report here - lots of new threads/task in here as well
        return false;
    }
    else
    {
        return true;
    }
}



我究竟做错了什么?

What am i doing wrong?

这是正确的方式还是我总异地

Is this correct way or am i total off?

编辑:

最重要的是,我的UI仍然必须响应!

推荐答案

听起来像是你想这样的事情。请纠正我,如果我misinterpretting你的意图...

Sounds like you want something like this. Please correct me if I am misinterpretting your intentions...

首先,在你的开球,设置为长期运行的任务,因此不会消耗从一个线程线程池,而是创建一个新的...

First, in your kick-off, set as a long running task so it doesn't consume a thread from the thread pool but creates a new one...

private void ViewBase_Loaded(object sender, RoutedEventArgs e)
{
    // store this references as a private member, call Cancel() on it if UI wants to stop
    _cancelationTokenSource = new CancellationTokenSource();
    new Task(() => CreateAndStartReportRequestTask(), _cancelationTokenSource.Token, TaskCreationOptions.LongRunningTask).Start();
}



然后,在你的报告看线程,循环,直至取消申请。如果没有工作,只等待15秒(这样,如果取消,将唤醒越快)取消标记。

Then, in your report watching thread, loop until cancel requested. If there is no work, just wait on the cancel token for 15 seconds (this way if cancelled will wake sooner).

private bool CheckReportRequestsAndGenerateReports()
{
    while (!_cancellationTokenSource.Token.IsCancelRequested) 
    {
    var possibleReportRequest = //Some linq query
    var reportRequestTask = Task.Factory.StartNew(() => noRequest = CheckReportRequestsAndGenerateReports(), _cancellationTokenSource.Token);

    if (noRequest)
    {
        // it looks like if no request, you want to sleep 15 seconds, right?
        // so we'll wait to see if cancelled in next 15 seconds.
        _cancellationTokenSource.Token.WaitHandle.WaitOne(15000);

    }
    else
    {
        // otherwise, you just want to wait till the task is completed, right?
        reportRequestTask.Wait(_cancellationTokenSource.Token);
    }
    }
}



我也警惕有你的任务揭开序幕更多的任务。我中有你的旋转起来这么多你就吃下过多的资源的感觉。我觉得你的计划是失败的主要原因是,你有:

I'd also be wary of having your task kick off more tasks. I have a feeling you are spinning up so many you're consuming too many resources. I think the main reason your program was failing was that you had:

     if (noRequest)
     {
         reportRequestTask.Wait(15000);
         reportRequestTask = null;
     }

这将立即返回,而不是等待15秒,是因为线程是在已经完成这一点。它切换到取消令牌(或 Thread.sleep代码(),但你不能那样容易放弃它)会给你等到你需要的处理。

This will return immediately and not wait 15s, because the thread is already complete at this point. Switching it to the cancel token (or a Thread.Sleep(), but then you can't abort it as easily) will give you the processing wait you need.

希望这可以帮助,让我知道,如果我关上我的假设。

Hope this helps, let me know if i'm off on my assumptions.

这篇关于如何创建一个线程/任务有一个连续的循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆