Click here to Skip to main content
15,921,113 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi all,
I have a MainForm, a MyClass and different DialogForms. I want to use a dataset for storing my combobox tables as long as my application runs, because every time opening a dilaog form I do not want to make any query to fill comboboxes. The combobox defined on MyClass and filled when MainForm. So, what is the best method for my situation? Using static parameter, or some smart suggetsions, etc. Thanks in advance...:confused:
Posted

Create a static Globals class that holds app-wide data members.

C#
public static class Globals
{
    public static DataSet MyData { get; set; }

    static Globals()
    {
        // initialize MyData property in the constructor with static methods
    }
}


This is the way I do it. I know - global data is "evil", but this is a handy solution to the "I want to get to it from anywhere" requirement.
 
Share this answer
 
v2
Comments
H.Johnson 3-Mar-11 7:54am    
Thanks for reply. You are right global data is evil. But, my actual aim is simply to hold a dataset on MyClass and access it when opening my DialogForm. So, how can I do this in a smart way?
#realJSOP 3-Mar-11 11:55am    
There's absolutely nothing wrong with doing it this way. It's static so that there's only one copy of it. You can put initiziation code into the Globals class that will take care of populating the dataset, and if you call that code from the Globals constructor, it will be available when your form is initially displayed. Just because someone else thinks a particular methodology is "evil" doesn't mean it ain't damn convenient. Besides considering globals to be "evil" is merely a guideline - kinda like the Bucaneer code.
Sergey Alexandrovich Kryukov 3-Mar-11 11:42am    
Simple and will work, but does not have to be static, see my comment to Griff's answer.
However, why not static? A 5 anyway.
--SA
What you really want to do here is caching.

When you application launches, it's going to need to get some data from a database or whatever storage you are using to populate your cache.

The logic I use here is like this...

Cache Logic Diagram[^]

So, the first time you call a method, it will invoke the database operation and cache the data. Next time you call the method, the data is retrieved from the Cache.

You can implement this using a CacheManager class, source as follows

NB: this using the HttpRuntime caching mechanism, so you'd need a reference to System.Web in your project

PasteBin source code for CacheManager[^]

You can then call like follows...

C#
/// <summary>
/// Execution delegate that returns some data
/// </summary>
/// <typeparam name="TValue">value</typeparam>
/// <returns>Business set</returns>
public delegate TValue DataRetrievalDelegate<TValue>();

public System.Data.DataTable GetCityData()
{
    return CacheManager.RetrieveFromCacheOrInvoke<System.Data.DataTable>("Cache:CityData",
       new DataRetrievalDelegate<System.Data.DataTable>(delegate()
       {
           // Your code here for retrieving data from some source!
           return new System.Data.DataTable();
       }));
}



I've put together a little demo project if you're struggling with this.

Retrieve From Cache Or Invoke Demo[^]

Have a look in the Program.cs file. Put a breakpoint on the first line...run the project through line by line.

Notice how the first time it will call the delegate method, the second time it will retrieve from the cache

:thumbsup:
 
Share this answer
 
v2
Comments
H.Johnson 3-Mar-11 10:24am    
Thanks, but there is a problem for some of the lines like Caching and Http. On the other hand, I have a WINFORM, not an Web Page. Caching is very nice, but if it is not suitable for WINFORM, could you suggest another intelligent solution please? On the other hand, when searching on the web, I have found this. What about it?Is it useless?

01.using System;
02.using System.Collections.Generic;
03.using System.Linq;
04.using System.Text;
05.using System.Threading;
06.
07.public class CacheManager
08.{
09. static System.Collections.Hashtable ht = new System.Collections.Hashtable();
10.
11. public static void AddItem(string key, object value, uint timeToCache)
12. {
13. if (timeToCache > 3600)
14. throw new ArgumentOutOfRangeException("Cache time cannot be more than 1 hour.");
15.
16. System.Threading.Timer t = new System.Threading.Timer(new TimerCallback(TimerProc));
17. t.Change(timeToCache * 1000, System.Threading.Timeout.Infinite);
18. ht.Add(t, key);
19. AppDomain.CurrentDomain.SetData(key, value);
20. }
21.
22. public static object GetItem(string key)
23. {
24. return AppDomain.CurrentDomain.GetData(key);
25. }
26.
27. private static void TimerProc(object state)
28. {
29. System.Threading.Timer t = state as System.Threading.Timer;
30.
31. if (t != null)
32. {
33. object key = ht[t];
34. ht.Remove(t);
35. t.Dispose();
36.
37. if (key != null)
38. AppDomain.CurrentDomain.SetData(key.ToString(), null);
39. }
40. }
41.}



Calling :
CacheManager.AddItem(cacheKey, myDataTable, 300);

Kindest regards...
Dylan Morley 3-Mar-11 11:16am    
Please see my updated answer: Demo project is available at the bottom now
Sergey Alexandrovich Kryukov 3-Mar-11 11:43am    
Very good in-depth stuff, my 5.
--SA
Dylan Morley 3-Mar-11 10:25am    
Did you see the line I wrote??

NB: this using the HttpRuntime caching mechanism, so you'd need a reference to System.Web in your project

Add the reference to System.Web in your project that will do the caching & it will work.
H.Johnson 3-Mar-11 18:20pm    
Dear Dylan,
thank you very much for your good explanations and wonderful method + sample source. That's really how a brief explanation could be. My 5. I just would like to ask some question regarding to positioning these logic to my project. Could you confirm the points below;

1) In my project there is MainForm, DialogForm and MyClass. I will add my project CacheManager and CachedData classes, is it true? Or is there anythink I should add to my project?

2) Shall I move CachedData class to MyClass? Or, should I use it seperately?

3) I think I call CachedData from MainForm. CachedData class going to Database and returns datatable (or I can change to return DatSet). The cached data is stored
on CachedData class? Is it true?

4) CacheManager class's task sets all the caching setup. Is it true?

5) Under this conditions, I think to build my logic like that; when MainForm load, I call CachedData. At this point, do I have to fill the returned datatable (or dataset) to a new variable on MainForm?
Because, I do not use this variable on MainForm. Actually I do not want to create a variable on MyClass to keep the cached data. Instead of this, I would like to
call CachedData.GetData() method to retrieve data directly without creating any variable. I mean;

//On CachedData class
DataSet ds = new DataSet();
ds = GetData();
myCombobox.DataSource = ds.Tables["Student"];

//Instead of this, should I use like below without creating a DataSet variable?;
myCombobox.DataSource = GetData().Tables["Student"];

I would be very appreciated if you suggest me the most suitable way according to my logic. Thanks in advance...
If the data it going to be the same for all parts of your application, then it does make some sense to hold it as a static property, probably in your MainForm, since that is the first thing loaded: it can set the values in it's Load event for everything else to use.
 
Share this answer
 
Comments
H.Johnson 3-Mar-11 7:54am    
Yes, the data is not changed everyday. The data is City names. So, I think to keep it on MyClass when MainForm is loaded. And whenever a DialogForm opens, I want to call this kept dataset to fill the comboboxes on my Dailog form. Any smart and intelligent method will be very appreciated.
Sergey Alexandrovich Kryukov 3-Mar-11 11:39am    
Griff, if your offer to put a property in a main form, it does not have to be static, because it is created first, you can pass its reference to other forms (but better interface reference).
--SA
#realJSOP 3-Mar-11 11:56am    
If you put the object into a global static class, it's even more convenient because it's available everywhere.
Sergey Alexandrovich Kryukov 3-Mar-11 14:21pm    
As I say, nothing wrong with that, especially of it is accessed from one thread, thread synchronization is not needed.
--SA
OriginalGriff 3-Mar-11 14:15pm    
You can pass the reference to other forms, but it gets messy: you have to be sure you have passed it all the way to all relevant forms/classes.
In practice, I would go with JSOP and create a static Globals class (I often do).
Dunno why I suggested putting it in the main form: I plead stupidity!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900