Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Using Asp.Net 4/c#
I want to store a list of items in memory (I use the term list generically) rather than list. I need to maintain a last used date for items in the list.
Effictively I need to lock, find the earliest date, update it and unlock and return the record.
As a relative newbie, I have a couple of questions:
What is the best way to store the data;
Is there a documented locking pattern I can use to ensure thread
safety.
From your description what you want is a queue & a locking mechanism around that queue. The queue is a first in first out container, which means objects will be dequeued in the order they are enqueued, guaranteeing your update order constraint. As for the synchronization constraint, because you want to do the work inside of the lock, you'll need a lock at a higher level than your queue. Something like this should do the trick but needs to be used the correct way, as a LockingDequeu() without dispose will permanently lock the queue.
public class MyQueue<T>
{
private readonly Queue<T> internalQueue = new Queue<T>();
private readonly object queueLocker = new object();
public Enqueue(T data)
{
internalQueue(data);
}
public IDisposable LockingDequeue(out T data)
{
var queueLock = new QueueLock(queueLocker);
data = internalQueue.Dequeue();
return queueLock;
}
private class QueueLock :IDisposable
{
private readonly object lockObject;
public QueueLock(object lockObject)
{
this.lockObject = lockObject;
Monitor.Enter(lockObject);
}
public void Dispose()
{
Monitor.Exit(lockObject);
}
}
}
Understand that the LockingDequeue call needs to be used within a using block. But the calling syntaxt would look like this:
var myQueue = new MyQueue<object>();
object obj;
using(myQueue.LockingDequeue(out obj))
{
//update date
//do some work
myQueue.Enqueue(obj);
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am trying to access a method, and a variable in that method, that is also in a separate thread from a GUI Textbox in Windows Forms.
Every other question people have is how to go the other way by accessing the GUI from a separate thread that's the opposite of what I'm trying to do.
public ClientWindow()
{
InitializeComponent();
var ItemThread = new Thread(new ThreadStart(ItemRun));
ItemThread.Start();
}
public void ItemRun()
{ //..
}
public void Return(object sender, KeyEventArgs e)
{ //need to access a variable in ItemRun() from here
}
Thanks for any answers.
You just need to make your Variable/s Global, also if you need thread safety you need use some sort of locking mechanism
// create global variable
private volatile int somevar;
// create a sync object to lock
private int _sync = new object();
...
public void ItemRun()
{
// make sure you lock it
// if there might be race conditions or you need thread safety
lock(_sync)
{
// update your global variable
somevar = 3;
}
}
public void Return(object sender, KeyEventArgs e)
{
// lock it again if you need to deal with race conditions
// or thread safty
lock(_sync)
{
Debug.WriteLine(somevar);
}
}
Update
volatile (C# Reference)
The volatile keyword indicates that a field might be modified by
multiple threads that are executing at the same time. Fields that are
declared volatile are not subject to compiler optimizations that
assume access by a single thread. This ensures that the most
up-to-date value is present in the field at all times.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm trying to create thread according to integer value. For example if the variable is '5', program should create 5 threads or variable is '2', program should create 2 threads, etc. But I can't understand which path I must follow.
It's just a matter of creating the Thread and start it. But I wouldn't suggest you to handle the thread explicitly, but to use Tasks or ThreadPool in order to execute multithreading work.
using System;
using System.Threading;
public class Program
{
public static void Main()
{
int numberOfRequestedThreads = 3;
for (int i = 0; i < numberOfRequestedThreads; i++)
{
var tempThread = new Thread(new ThreadStart(DoWork));
tempThread.Name = i.ToString();
tempThread.Start();
}
}
public static void DoWork()
{
Console.WriteLine("Thread#{0} is now working!", Thread.CurrentThread.Name);
}
}
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
Maybe I've misunderstood how constructors work, but in any case, I'm trying to create an array and populate it in the constructor.
I have the following code --
class ClsDeck
{
private string[] deck = new string[52];
private string[] hand = new string[12];
BuildDeck()
{
//lots of code assigning images to each individual element of the "deck" array.
}
//many other methods that need to be called by a form.
}
Visual Studio 2012 insists that the method have a return type. I have simply added "void" to the BuildDeck method, and the error disappeared, but every example I've seen of a constructor has to have the same name as the class, and it has been the only method in the class.
That won't even compile. BuildDeck() has no return type. Constructor names need to match the class name (including case). Replace BuildDeck with ClsDeck().
By definition, a constructor is a method that 1.) has the same name as the class, and 2.) has no return value.
In your example above, "BuildDeck" is not a constructor ... it is a method, and therefore must specify a return type (or "void" if it doesn't return anything).
If you want a constructor, rename "BuildDeck" to "ClsDeck".
The constructor of your class is actually missing.
Make the following changes, and your code will compile:
class ClsDeck
{
private string[] deck = new string[52];
private string[] hand = new string[12];
public ClsDeck()
{
// Place your array initializations here.
}
private void BuildDeck()
{
//lots of code assigning images to each individual element of the "deck" array. }
//many other methods that need to be called by a form.
}
}
That will not work or compile. In order to achieve what you want, you could have a constructor for ClsDeck and call BuildDeck
class ClsDeck {
private string[] deck = new string[52];
private string[] hand = new string[12];
ClsDeck() { //lots of code assigning images to each individual element of the "deck" array. }
//many other methods that need to be called by a form.
BuildDeck();
}
private void BuildDeck() {
//Build your deck
}
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Can I safely read a IsBusy boolean property for an instantiated singleton from multiple threads without causing any thread-safety issues, or am I already in dangerous waters?
Unless you have any memory barriers, you're potentially in dangerous waters, if the value can ever change.
Let's take the singleton part of this out of the equation, as it's not particularly relevant. Consider this simple example:
// Not safe!
public class BusyIndicator
{
public bool IsBusy { get; set; }
}
Now if you have one thread which is along the lines of:
foo.IsBusy = true;
// do some work
foo.IsBusy = false;
and another thread, only started after IsBusy is set to true, that has:
// Do some work
while (foo.IsBusy) { }
... then it's possible that the second thread will spin forever... there's no memory barrier to ensure that it "sees" the change from the first thread.
You can implement this safely either using locking or using Interlocked, e.g.
// Safe (in terms of memory barriers)
public class BusyIndicator
{
private int busy = 0;
public bool IsBusy
{
get { return Interlocked.CompareExchange(ref busy, 0, 0) == 1; }
set { Interlocked.Exchange(ref busy, value ? 1 : 0); }
}
}
If you have defined the property IsBusy as follows, then you can definitely have thread safety issues:
public bool IsBusy { get; set; }
The big issue here is the value can be checked and then changed before the value is set. That means you have a race condition. ONE way to solve this is:
// this is going to keep trying to lock until it succeeds, after which it
// will do whatever work needs done.
while (true) {
bool lockObtained = false;
lock (objectInstance) {
if (!objectInstance.IsBusy) {
lockObtained = true;
objectInstance.IsBusy = true;
}
}
if (lockObtained) {
// good to go here
// and don't forget to clear the IsBusy
objectInstance.IsBusy = false;
break;
}
}
This uses the built in .NET locking mechanism to lock the object so you can check and set without worrying about process preemption in the middle.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Why is this lock not working?
CheckActivity is generated from Mouse/Keyboard Windows hook. Any hint how to make this lock to work?
private void CheckActivity(KeyboardMouseKey k)
{
lock(this)
{
if (_map)
{
_map = false;
if (openFileDialogSelectAudio.ShowDialog() == DialogResult.OK)
MapSound(k, openFileDialogSelectAudio.FileName);
}
else
{
///play
foreach (var m in _mappings.Where(m => m.Key.Equals(k)))
m.Value.Play();
}
UpdateGui();
}
}
You are using lock(this).
If Check Activity is called on different objects, lock(this) will not prevent for making sure that only one thread is executing CheckActivity (which appears to be the purpose of the lock)
Use lock on static object to make it work.
Example:
private static readonly object lockObj = new object();
...
lock(lockObj)
{
....
}