Ha várni kell a Windowsban – A jó öreg homokóra
Gyakran fordul elő, hogy homokórát kell megjelenítenünk, mert valamilyen művelet hosszabb időt vehet igénybe. A felhasználó pedig várakozzon, ahelyett, hogy a beviteli mezőket próbálja szerkeszteni vagy a gombokat működésre bírni.
Régebbi programozási nyelvekben (Delphi, FoxPro) a hosszú műveletek automatikusan beállították a homokóra üzemmódot. Viszont nem kezelték jól a beágyazott műveleteket, azaz 10 darab SELECT végrehajtása egymás után 10 homokórás villogást eredményezett. Ez a mai világban inkább szégyenletes, mint felhasználóbarát.
Ezt a problémát oldottuk meg az alábbi kódrészlettel:
using System; using System.Windows.Forms;
namespace SymbolTech.Common
{
public class WaitCursor : IDisposable
{
private static int waitcursorlevel = 0;
public WaitCursor()
{
waitcursorlevel++;
if (waitcursorlevel > 0)
Cursor.Current = Cursors.WaitCursor;
}
public void Dispose()
{
waitcursorlevel--;
if (waitcursorlevel == 0)
Cursor.Current = Cursors.Default;
}
}
}
Minden (hosszabb) műveletet beágyazunk egy using(new WaitCursor()) blokkba. Ezzel a következő előnyöket érjük el:
- A műveletek minden esetben “homokórázni” fognak.
- A beágyazott műveletek (külső blokk már homokórában dolgozik, a belső, mondjuk 100 iteráció is bekapcsolja a homkórát) nem fogják villogtatni a kurzort.
- Véletlenül sem felejtjük el visszakapcsolni az alapértelmezett kurzort, amennyiben a műveletek végrehajtásra kerültek.
Lássunk egy példát, a használatára:
private void DummyMethod()
{
using (new WaitCursor())
{
Thread.Sleep(100);
}
}
private void button1_Click(object sender, EventArgs e)
{
using (new WaitCursor())
{
Thread.Sleep(500);
for (int i = 0; i < 10; i++)
DummyMethod();
}
}
A példában egy beágyazott, többször (10x) végrehajtott műveletet látunk, amelyek összességében 1.5mp-re átkapcsolnak homokórára, de közben nem villog a kurzor.

július 12th, 2009 at 10:24
A dolog ugyan nem threadsafe, de szép, tömör megoldás desktop alkalmazások fejlesztéséhez.
július 12th, 2009 at 11:05
A Thread-ek általában nem szoktak homokórát működtetni, mert a felhasználót nem nagyon érdekli és gátolja, ha a háttérben megy valami.
Abban igazad van, hogy amennyiben egy metódus néha thread-ből, néha nem threadből hívja, akkor a WaitCursor bent dönthetne arról, hogy állít-e homokórát. Thread.CurrentThread.
Desktop alkalmazásban Thread elég ritka…