Home > other >  ThreadPool.QueuedWorkerItem(new WaitCallback(procedure) object) returns true but procedure does not
ThreadPool.QueuedWorkerItem(new WaitCallback(procedure) object) returns true but procedure does not

Time:07-07

I have the following code:

static void Main(string[] args)
{

    runStartedJobs();
}

static void runStartedJobs()
    {

        List<Job> runningJobs = Job.getQueue(1);

        for (int j = 0; j < runningJobs.Count; j  )
        {
            if (runningJobs[j].InputFile.Trim().Length == 0
                || runningJobs[j].SubscriberColumn > 0
                || runningJobs[j].NpsGroupColumn > 0)
            {
                string queueFolder = @"c:\temp\";
                string searchString = "cde_"   runningJobs[j].JobID.ToString("0")   "_*.json";
                string[] jsonFiles = Directory.GetFiles(queueFolder, searchString, SearchOption.TopDirectoryOnly);
                for (int f = 0; f < jsonFiles.Length; f  )
                {
                    StreamReader jsonReader = new StreamReader(jsonFiles[f]);
                    string jsonThread = jsonReader.ReadToEnd();
                    jsonReader.Close();
                    List<NPS_Package> packages = JsonConvert.DeserializeObject<List<NPS_Package>>(jsonThread);
                    bool threadQueued = ThreadPool.QueueUserWorkItem(new WaitCallback(GetData), packages);
                }
                //Console.ReadLine();

          }

This results in 2 calls to QueueUserWorkItem, both returning true, but the routine exits immediately, and it does not appear that the code in GetData gets executed (breakpoint set at beginning of routine does not get hit)

If i put a Console.ReadLine() after the for loop then the breakpoint does get hit.

I suspect I need to wait, but I may have other jobs that I want to start before this job finishes.

CodePudding user response:

The main thread will complete and the application exit before those background tasks are performed. You would need that main thread to wait somehow. Probably best to use Tasks rather than the ThreadPool and then you can call Task.WaitAll.

CodePudding user response:

As mentioned in the other answer, you need to use something like tasks and then await for all your tasks to finish. You should also convert the rest of the code to await as well.

For example

static async Task Main(string[] args)
{
    await runStartedJobs();
}

static async Task runStartedJobs()
{
    List<Job> runningJobs = Job.getQueue(1);
    var tasks = new List<Task>();

    foreach (var job in runningJobs)
    {
        if (!(job.InputFile.Trim().Length == 0
            || job.SubscriberColumn > 0
            || job.NpsGroupColumn > 0))
        {
            continue;
        }
        string queueFolder = @"c:\temp\";
        string searchString = $"cde_{job.JobID:0}_*.json";
        foreach (var file in Directory.EnumerateFiles(queueFolder, searchString, SearchOption.TopDirectoryOnly))
        {
            string jsonThread;
            using (StreamReader jsonReader = new StreamReader(file))
                jsonThread = await jsonReader.ReadToEndAsync();
            List<NPS_Package> packages = JsonConvert.DeserializeObject<List<NPS_Package>>(jsonThread);
            tasks.Add(Task.Run(async () => await GetData(packages)));
        }
    }

    await Task.WhenAll(tasks);
}
  • Related