Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy do all items in my task queue get assigned the same value?
    primarykey
    data
    text
    <p>I have been trying to do due-diligence before asking this question, but I can't seem to find what I'm looking for. I believe that I'm running up against <a href="http://en.wikipedia.org/wiki/Producer-consumer_problem" rel="nofollow">producer-consumer problem</a>. I'm writing a winforms application in C# that uses two threads: one for the UI, and one for a background worker. Items are added to a task queue via the submit button event handler (ie. whenever the user hits "Submit"). If there is nothing in the queue already, then the background worker is called and starts to process the queue. If the background worker is busy, then the task is simply added to the queue. Theoretically, the background worker will move on to the next item in the queue when it finishes its current work.</p> <p>In my UI thread, I have the following code that instantiates a DiscQueue object and then adds items to its queue:</p> <pre><code>private DiscQueue discQueue = new DiscQueue(); this.discQueue.AddToQueue(currentCD); </code></pre> <p>Below is my DiscQueue class. My AddToQueue function adds the disc to the queue and then calls RunWorkerAsync() if the bw is not already busy. Then, in bw_DoWork, I grab an item from the queue and do the work on it that I need to do. When the bw completes its task, it should call bw_RunWorkerCompleted, which should direct it to continue working through the queue if there are more items in the queue.</p> <pre><code>class DiscQueue { private Queue&lt;Disc&gt; myDiscQueue = new Queue&lt;Disc&gt;(); private BackgroundWorker bw = new BackgroundWorker(); // Initializer public DiscQueue() { // Get the background worker setup. this.bw.WorkerReportsProgress = false; this.bw.WorkerSupportsCancellation = false; this.bw.DoWork += new DoWorkEventHandler(bw_DoWork); } public void AddToQueue(Disc newDisc) { this.myDiscQueue.Enqueue(newDisc); if (!this.bw.IsBusy) { this.bw.RunWorkerAsync(); } } private void bw_DoWork(object sender, DoWorkEventArgs e) { DiscPreparationFactory discToPrepare = new DiscPreparationFactory(); Disc currentDisc = new Disc(); currentDisc = this.myDiscQueue.Dequeue(); discToPrepare.PrepareAndPublish(currentDisc); } private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (this.myDiscQueue.Count &gt; 0) { this.bw.RunWorkerAsync(); } } } </code></pre> <p>In testing, I discovered that adding items to the queue in rapid succession somehow clobbers the queue so that all items in the queue are assigned the value of (perhaps the reference to?) the last item added to the queue. As I stepped through the code in debugging, this seems to happen by the time you get to if (!this.bw.IsBusy) in the AddToQueue function. I'm not sure what's going on. </p> <p>Aside from answering my specific question, I'm sure that I'm doing things bass-ackwards, and I'd be very happy to know the "right way" to do this.</p> <p><strong>EDIT:</strong> Here is my Disc class:</p> <pre><code>public class Disc { public enum DiscFormat { Audio, Data, } private string sku; private int quantity; private DiscFormat format; public string Sku { get { return this.sku; } set { this.sku = value; } } public DiscFormat Format { get { return this.format; } set { this.format = value; } } public int Quantity { get { return this.quantity; } set { this.quantity = value; } } } </code></pre> <p><strong>EDIT 2:</strong> My DiscQueue object is instantiated in my MainForm.cs file as follows:</p> <pre><code>public partial class MainForm : Form { Disc currentCD = new Disc(); private DiscQueue discQueue = new DiscQueue(); public MainForm() { // Do some stuff... } // Skipping over a bunch of other methods... private void buttonSubmit_Click(object sender, EventArgs e) { currentCD.Sku = this.textBoxSku.Text; currentCD.Quantity = (int)this.numericUpDownQuantity.Value; if (this.radioButtonAudio.Checked) currentCD.Format = Disc.DiscFormat.Audio; else currentCD.Format = Disc.DiscFormat.Data; this.discQueue.AddToQueue(currentCD); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload