0

I'm writing an application where I have a class Rechnungsleser with 2 methods and some fields. Fields:

invoices = new BlockingCollection<Invoice>(new ConcurrentQueue<Invoice>());
// Total number of invoices in the XML
invoicesToProcess = XDocument.Load(sourceFile).Root.Elements().Count();
// Number of invoices consumed
invoicesProecessed = 0;


public void ReadRechnungslauf() (below)
using (XmlReader rechnungsreader = XmlReader.Create(sourceFile))
{
    // Iterate over whole file
    while (!rechnungsreader.EOF)
    {
        if (someCondition)
        {
            XElement rechnung = XNode.ReadFrom(rechnungsreader) as XElement;
            // Some minor change
            Helper.RemoveAllNamespaces(rechnung);

            if (rechnung != null)
            {
                try
                {
                    // Decent change, takes XElement, reads and changes some Elements, return object of type Invoice
                    invoices.Add(CreateRechnung(rechnung, possibleOverlays));
                }
                catch (Exception e)
                {
                    Log(e)
                    throw;
                }

            }
        }
        else
        {
            rechnungsreader.Read();
        }
    }
}

public void ProcessRechnungslauf()
{  
    Rechnung currentRechnung;
    // Check that all invoices are processed
    while (invoicesToProcess != invoicesProecessed)
    {
         // Take next enqueued item
         currentRechnung = rechnungen.Take();
         if (currentRechnung.PrintMode.Equals("Online"))
         {
              // Very computing heavy method
              printer.PrintRechnung(currentRechnung);
         }
         invoicesProcessed++;
     }
}

I initialize both methods like this:

using (Rechnungsleser reader = new Rechnungsleser()
{
   Task readingTask = Task.Factory.StartNew(() =>
   {
       reader.ReadRechnungslauf();
   });
   Task processingTask = Task.Factory.StartNew(() =>
   {
       reader.ProcessRechnungslauf();
   });
   Task.WaitAll(readingTask, processingTask);
}

When I check the log it first reads all invoices and places them in the queue and then starts processing them. How can I ensure the parallelism? Is it only because ProcessRechnungslauf() needs much more performance then ReadRechnungslauf()?
Should I use Threads or the TaskParallelLibrary? Why?
My understanding is, that a Task takes an available Thread from Threadpool and executes it. I don't see why these 2 Tasks shouldn't work together.

Peter
  • 1,844
  • 2
  • 31
  • 55
  • The code provided isn't enough to make any judgment. It's not clear what happens inside `ReadRechnungslauf`, what the variables `invoicesToProcess` and `invoicesProecessed` are. – Dmytro Mukalov Mar 29 '19 at 09:12
  • Added more code, I don't think it is particullary more descriptive, since it's not really a lot that happens in `ReadRechnungslauf` – Peter Mar 29 '19 at 09:22
  • Hmm, looks like a simple producer consumer pattern. But the _ProcessRechnungslauf()_ should perform **invoices.Take()** instead of **rechnungen.Take()** since _rechnungen_ is unknown according to your code sample. Have you tried to replace _if (currentRechnung.PrintMode){ ... }_ with some other code to check if there is something blocking/slowing down? – user1470240 Mar 29 '19 at 10:07
  • Also, try marking the two threads as long-running using `TaskCreationOptions.LongRunning`. – Nick Mar 29 '19 at 10:10
  • As soon you don't have any logging inside `ProcessRechnungslauf` I presume it happens somewhere inside the `PrintRechnung`. High chances that tasks actually start in parallel but as parsing data is faster process it quickly prints all its messages into the log, while long running `PrintRechnung` starts printing into the log from some moment which happens later than `ReadRechnungslauf` completes. – Dmytro Mukalov Mar 29 '19 at 10:29

0 Answers0