|
|
Közzétéve 2017. 10. 12. 13:12:51
|
|
|

A C# időzítő osztályáról A C#-ban három időzítő osztály van
1. Definiálja a System.Windows.Forms fájlban
2. Definiálva a System.Threading.Timer osztályban
3. Definiálva a System.Timers.Timer osztályban
A System.Windows.Forms.Timer a WinForm-ra van alkalmazva, a Windows üzenetmechanizmuson keresztül valósítható meg, hasonlóan a VB vagy Delphi időzítő vezérléséhez, és belsőleg a SetTimer API segítségével valósítható meg. Fő hátránya, hogy az időzítés nem pontos, és üzenetciklusnak kell lennie, amely a konzol alkalmazás számára nem elérhető.
A System.Timers.Timer nagyon hasonlít a System.Threading.Timer-hez, ezek a .NET Thread Poolon keresztül valósulnak meg, könnyű, pontos időzítéssel, és nincs különleges követelmény az alkalmazásokhoz és üzenetekhez. A System.Timers.Timer WinForm-ra is alkalmazható, teljesen lecserélve a fent említett időzítő vezérlést. Hátrányuk, hogy nem támogatják a közvetlen húzás-dobást, és kézi kódolást igényelnek.
Példa:
Használd a System.Timers.Timer osztályt
System.Timers.Timer t = új System.Timers.Timer(10000); Indítsd be az Timer osztályt, és állítsd be az intervallumot.
t.Elapsed += új System.Timers.ElapsedEventHandler(theout); Végrehajtsa az eseményeket, amikor eljár az idő;
t.AutoReset = true; Állítsuk be, hogy egyszer (hamis) vagy minden idő (true) hajtsunk végre;
t.Enabled = true; hogy végrehajtsuk-e a System.Timers.Timer.Elapsed eseményt;
public void theout (object source, System.Timers.ElapsedEventArgs e)
{
MessageBox.Show("OK!");
}
Kísérleti elemzés a három időzítő használata közötti hasonlóságokról és különbségekről a C#-ban
http://dotnet.chinaitlab.com/CSharp/737740.html
Háromféle időzítő érhető el C#-ban:
1. Windows-alapú standard timer (System.Windows.Forms.Timer)
2. Szerveralapú időzítő (System.Timers.Timer)
3. Szálozási időzítő (System.Threading.Timer)
Nézzünk át néhány kisebb kísérletet, hogy elemezzük a három időzítő hasonlóságait és különbségeit, különösen a szálhoz kapcsolódó részt.
Kísérleti példa képernyőképe:
1. Szabványos Windows-alapú időzítő (System.Windows.Forms.Timer)
Az első dolog, amit érdemes megjegyezni, hogy a Windows Timer egyszálas környezetekre van tervezve
Ez az időzítő már a Visual Basic 1.0 verziótól jelen van a terméken, és nagyrészt változatlan maradt
Ez az időzítő a legegyszerűbb, egyszerűen húzd a Timer vezérlőt az eszköztárból az űrlapra, és állítsd be a tulajdonságokat, mint az események és intervallumok
A kísérleti eredmények teljesen összhangban vannak az egyszálas megoldás jellemzőivel is:
1. Amikor ezt az időzítőt elindítják, a gyermekszál azonosítója megjelenik az alábbi gyermekszál azonosító listában, és ugyanaz, mint a fő szál azonosítója
private void formsTimer_Tick(object sender, EventArgs e)
{
i++;
lblSubThread.Text += "Alszál végrehajtása, szálazonosító:" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + "\r\n";
}
2. Ha a fő szálat 5 másodpercre megállítják, a gyermekszál megállítja a végrehajtást, és ha a korábban felfüggesztett gyermekszál 5 másodperc után nem indul el, a következő gyerek szálat közvetlenül lefuttatják (vagyis néhány sor értéket ad ki).
System.Threading.Thread.Sleep(5000);
3. Ha egy gyermek folyamat eseményeit 5 másodpercre megállítják, a fő ablak 5 másodpercig nem reagál
4. Definiáljunk egy szálas statikus változót:
[ThreadStatic]
privát statikus int i = 0;
Hozzáadj egyet minden alszál eseményhez, majd kattints a thread statikus változó értékére, hogy megkapd a megnövekedett i értéket
2. Szerveralapú időzítő (System.Timers.Timer)
A System.Timers.Timer nem támaszkodik űrlapoktól, felébreszti a szálakat a szálkészletből, és a hagyományos időzítő frissített változata, amely szerverkörnyezetben futásra optimalizált
A VS2005 szerszámosdobozban nincsenek kivált vezérlők, ezért manuálisan kell kódolni az időzítő használatához
Kétféleképpen lehet használni,
1. Csatolj az űrlaphoz a SynchronizingObject tulajdonságon keresztül
System.Timers.Timer timersTimer = új System.Timers.Timer();
timersTimer.Enabled = hamis;
timersTimer.Intervall = 100;
timersTimer.Elapsed += új System.Timers.ElapsedEventHandler(timersTimer_Elapsed);
timersTimer.SynchronizingObject = ez;
Így a kísérlet szinte ugyanúgy működik, mint egy hagyományos Windows-alapú időzítő, kivéve a fenti második kísérletet, bár az alszál végrehajtása is megszünetel, de 5 másodperc után minden korábban sorba helyezett feladat elindul (azaz néhány értéksor nem hiányzik).
2. Ne használd a SynchronizingObject tulajdonságot
Ez a módszer többszálú, vagyis a kezdő gyermekszál és a fő forma nem ugyanazon a szálon vannak. Ugyanakkor van egy probléma is: mivel az alszál külön szál, az űrlap vezérlői nem férhetnek hozzá, csak egy proxyn keresztül érhető el:
delegate void SetTextCallback(string text);
Forrás: (http://blog.sina.com.cn/s/blog_5aeeb8200100bhc4.html) - (Turn) Három időzítő objektum összehasonlítása a C#_dash_Sina blogban
。
。
void timersTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
//使用代理
string text = "gyermekszál végrehajtása, szálazonosító:" + System.Threading.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = új SetTextCallback(SetText);
ez. Invoke(d, új objektum[] { text });
i++;
}
private void SetText(string text)
{
lblSubThread.Text += szöveg;
}
Így ismét a következő eredményeket kapjuk meg a kísérletből:
1. Amikor ez az időzítő elindul, a gyermekszál azonosítója megjelenik az alábbi gyermekszál azonosító listában, és eltér a fő szál azonosítótól
2. Amikor a fő szálra kattintasz, hogy 5 másodpercre szünetelj meg, az alszál tovább fut (lehet, hogy nem látható az interfészen, de könnyen látható, ha a fájlt az alszálban kitöltöd)
3. A gyermek folyamat eseményeinek 5 másodperces szünete nem okozza a fő ablak választalanságát
4. Hozzáadj egyet a szál statikus változóhoz minden alkalommal az alszál eseményben, majd kattints rá, hogy a szál statikus változója értéke-e 0 vagy 0 (a fő ablakban nem változtatja meg a szál statikus változóját).
3. Szálozási időzítő (System.Threading.Timer)
A szálidőzítők sem támaszkodnak űrlapokra, egyszerű, könnyű időzítők, amelyek visszahívási módszereket használnak események helyett, és szálpool szálakon alapulnak.
A szálidőzítők hasznosak olyan helyzetekben, amikor üzenetek nem küldenek a szálakon.
Íme, hogyan lehet használni:
System.Threading.Timer threadTimer;
public void ThreadMethod (Object state)
{
//使用代理
string text = "gyermekszál végrehajtása, szálazonosító:" + System.Threading.CurrentThread.ManagedThreadId.ToString() + "\r\n";
SetTextCallback d = új SetTextCallback(SetText);
ez. Invoke(d, új objektum[] { text });
i++;
}
private void Form1_Load(object sender, EventArgs e)
{
threadTimer = új System.Threading.Timer (új System.Threading.TimerCallback(ThreadMethod), null, -1, -1);
}
Szünetkód:
threadTimer.Change(-1, -1);
A kísérlet hatása megegyezik a szerveralapú időzítő második módjával (System.Timers.Timer).
Természetesen a konkrét használati módszerek és elvek eltérnek, a legfontosabb, hogy ez a módszer az ügynök metódust használja az esemény metódus helyett, és külön is végrehajtható anélkül, hogy űrlapokra és komponensekre támaszkodna
Az alábbiakban egy táblázatot tartalmaz, amelyet külföldiek foglaltak össze (a három módszer közötti különbséget):
Feature descrip{filter}tion System.Timers.Timer System.Threading.Timer System.Windows.Forms.Timer
Támogatás hallgatók hozzáadására és eltávolítására az időzítő bevezetése után. Igen, nem, igen.
Támogatja a visszahívásokat a felhasználói felület szálán, Yes No Yes
Visszahívások a szálakból származó szálakból Igen Igen Nem.
Támogatja a drag-and-drop funkciót a Windows Forms Designer Yes No Yes
Szerver többszálas környezetben való futtatásra alkalmas Igen Igen Nem
Támogatja az időzítő inicializációtól a visszahívásig történő tetszőleges állapot továbbítását. Nem, igen, nem
Megvalósítja az IDisposable Igen Igen Igen
Támogatja az egyszeri visszahívásokat, valamint időszakosan ismétlődő visszahívásokat Igen, Igen, Igen Igen
Elérhető az alkalmazási tartományhatárokon át. Igen, igen, igen.
Támogatja az IComponent – hostálható egy IContainer Yes No Yes |
Előző:c# Lamda kifejezéshalmazának decsoportozása, hogy a minimum értéket vegyükKövetkező:Linq: Soha ne használd a Count() > 0 gombot, hogy megállapítsuk, a halmaz nem üres-e
|