Suppose I have a class that should generate some ID for me (for example, a GUID). Now, unfortunately, generating IDs is a somewhat long process, and if I need a hundred of them, I am faced with the problem of significant slowdown. To avoid this, I save the queue of the pre-generated identifier, and when this queue starts working on them, I use BackgroundWorker to create new ones and place them in the queue. But there are some problems that I have encountered. The biggest at the moment is how to make sure that if the queue ends on identifiers, the main thread expects BackroundWorker to generate and put them in the queue. Here is the code that I have at the moment.
public class IdGenerator { private Queue<string> mIds = new Queue<string>(); private BackgroundWorker mWorker = new BackgroundWorker(); private static EventWaitHandle mWaitHandle = new AutoResetEvent(false); public IdGenerator() { GenerateIds(); this.mWorker.DoWork += new DoWorkEventHandler(FillQueueWithIds); } private void GenerateIds() { List<string> ids = new List<string>(); for (int i = 0; i < 100; i++ ) { ids.Add(Guid.NewGuid().ToString()); } lock (this.mIds) { foreach (string id in ids) { this.mIds.Enqueue(id); } } } public string GetId() { string id = string.Empty; lock (this.mIds) { if (this.mIds.Count > 0) { id = this.mIds.Dequeue(); } if (this.mIds.Count < 100) { if (!this.mWorker.IsBusy) { this.mWorker.RunWorkerAsync(); } } } if (this.mIds.Count < 1) { mWaitHandle.WaitOne(); } return id; } void FillQueueWithIds(object sender, DoWorkEventArgs e) { GenerateIds(); mWaitHandle.Set(); } }
Obviously, this is not working properly. It seems that I have a problem with the correct time to call the WaitOne and Set methods. And sometimes the IsBusy property returns true, although the worker has already completed his work.
EDIT:
Its WinForm and I have to use .NET 2.0
source share