Amir said:
Hi everyone
I have to make a global cache in a windows application to store few
data in the application's lifetime.
What do you mean by a global cache?
I guess you mean that you have data that you want to be accessed by
multiple threads in your application.
What's the best way to do that?
If you have a single thread then there is no problem. You simply create
static (Shared) fields in a class and access them from your objects:
// C#
class Global
{
public static string Name = "my name";
}
// other code
class MyClass
{
public string SwapData(string newName)
{
string temp = Global.Name;
Global.Name = newName;
return temp;
}
}
If you want to store generic data then the Global class could have a
static field that is a Hashtable and you could give each item of data a
name which you use as the index to access the data in the Hashtable.
If you have multiple threads then it gets complicated. Not just because
those threads will want to access the data concurrently, but because
multithreading and WinForms has pitfalls. The main problem is that you
*must not* allow the main thread (the one that calls Application.Run) to
block. So if you use thread synchronization (like Monitor or Mutex) to
act as a gate keeper to the global data, you must not allow the main
thread to access the global data (because it might be blocked while
calling Monitor.Enter or trying to access the Mutex).
One idea would be to implement the global data as a Hashtable in your
main form and make sure that only the main thread can access it. To do
this your other threads should get the ISynchronizeInvoke on the form,
and then call BeginInvoke on a delegate to a method on your form that
has access to the Hashtable. BeginInvoke guarantees that the main thread
will run the delegate. The data will be returned when you call
EndInvoke:
class MainForm : Form
{
Hashtable data = new Hashtable();
public object GetData(string name)
{
return data[name];
}
public void SetData(string name, object item)
{
data.Add(name, item);
}
delegate object getData(string n);
// this is the thread procedure passed to ThreadStart delegate
public void ThreadProc()
{
ISynchronizeInvoke invoke = this as ISynchronizeInvoke;
getData del = new getData(GetData);
IAsyncResult ar = invoke.BeginInvoke(del, new object[]{"myData"});
// get the data
object myData = invoke.EndInvoke(ar);
}
}
If the data returned is a reference type then you still have to be
careful about access from multiple threads.
Richard