I\'ve got a bit of a problem with making my data loading and filtering thread safe.
The following code on my control\'s base class which handles all the data populat
See Thread Synchronization (C# Programming Guide):
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Function()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
Edit: You don't want two threads entering Populate, so you could do something as bellow:
public void Populate(bool reload)
{
lock (lockThis)
{
// Disable the filter options
IvdSession.Instance.FilterManager.SetEnabledState(this.GetType(), false);
// do actual work.
}
}
Edit2: You got good thing going with BackgroundWorker, so maybe you could do something like this to let the other thread wait.
public void Populate(bool reload)
{
while (this.DataWorker.IsBusy) {
Thread.Sleep(100);
}
// Disable the filter options
IvdSession.Instance.FilterManager.SetEnabledState(this.GetType(), false);
// Perform the population
this.DataWorker.RunWorkerAsync(reload);
}
First, add a lock around your Populate
method body:
private object _exclusiveAccessLock = new object();
public void Populate(bool reload)
{
lock (_exclusiveAccessLock)
{
// start the job
}
}
This will help you avoid a race condition (although: if I got it right, since you are using a Windows.Forms Timer, it will always fire from the Gui thread, so they should never be executed exactly at the same time).
Next, I am not sure if you should throw the exception at all. You can, for example, set an additional flag that shows you that the worker hasn't finished yet, but that is what IsBusy
should tell you anyway.
Then there is the m_BlockFilter
flag. I cannot see where you are setting it from. It should be set inside the lock also, not in the background thread, because in that case you cannot be sure that it will not be delayed. You also need to make the field volatile if you are going to use it as a cross-thread flag.