Reputation: 5458
I have 2 secondary threads running in an C# Win Application.
The first thread reads Sql Server profile messages and adds it as a string to a list box to form a sort of queue. The other thread will send these trace messages one by one and correspondingly remove them from the list.
Now I am very much sure that it will cause problems. Any way to make sure that only a single thread will be able to access one of the two functions:
void AddItemThreadSafe(string item)
{
this.Invoke((MethodInvoker)delegate
{
listBoxCollection.Items.Add(item);
});
}
void RemoveItemThreadSafe()
{
this.Invoke((MethodInvoker)delegate
{
listBoxCollection.Items.RemoveAt(0);
});
}
Upvotes: 2
Views: 2943
Reputation: 5260
Use the built-in Thread-Safe Collections like ConcurrentBag Class
From your question Isaw that you need some kind of queue, so use ConcurrentQueue Class
Upvotes: 1
Reputation: 34018
The good news is that the Invoke
method on the form already synchronizes for you. That's the whole point of Invoke
: to queue the method/delegate so that it runs on the one and only UI thread that created the form.
Upvotes: 2
Reputation: 21927
In general, use a lock
to synchronize thread access to a section of code.
private static object listLocker = new object();
void AddItemThreadSafe(string item)
{
this.Invoke((MethodInvoker)delegate
{
lock (listLocker)
{
listBoxCollection.Items.Add(item);
}
});
}
void RemoveItemThreadSafe()
{
this.Invoke((MethodInvoker)delegate
{
lock (listLocker)
{
listBoxCollection.Items.RemoveAt(0);
}
});
}
In this particular case (someone correct me if I'm wrong), I believe the fact that you are invoking the methods from the same object already synchronizes the access, making the lock redundant.
Upvotes: 5