Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Using pattern

15.32 - 14. dubna 2008 | ASP.NET 2.0

Je tomu již dlouhá doba, co jsem psal spotík o užívání bloku using v jazyce C# pro třídy implementující rozhranní System.IDisposable. Tohoto bloku se dá využít k logickému členění kódu do bloků a vytvořit tak syntax sugar na úrovni API.

Ukázky užití

S using patternem se v moderních API dá potkat celkem často. První ukázka je z mockovacího frameworku Rhino Mocks. Používá se pro nahrávání a přehrávání chování mockovaného objektu.

MockRepository mocks = new MockRepository();
IDependency dependency = mocks.CreateMock<IDependency>();

using(mocks.Record()) {
    Expect.Call(dependency.GetSomething("parameter")).Return("result");
    dependency.DoSomething();
}

using(mocks.Playback()) {
    Subject subject = new Subject(dependency);
    subject.DoWork();
}

Using pattern usnadňuje čtení takovéhoto kódu a hned je jasná i logická struktura.

Další ukázka pochází z ASP.NET MVC frameworku, kde se using pattern používá v HTML helperu pro generování formuláře.

<% using(Html.Form<HomeController>(action => action.Index())) { %>
...
<% } %>

Implementace

Základem, tedy, je blok using, který slouží k bezpečnému zavolání metody Dispose objektu implementujícího rozhranní System.IDisposable. Jak na to, když v using bloku předáváme metodu a ne objekt? Jednoduše, musíme vrátit v metodě objekt, který se o špinavou práci postará. V podstatě ani nemusí být nijak inteligentní.

public class UsingPattern : IDisposable {

  private WorkerMethod _method;

  public delegate void WorkerMethod();

  public UsingPattern(WorkerMethod method) {
    _method = method;
  }

  public void Dispose() {
    _method();
  }
}

Užití v našem API je pak celkem triviální.

public class SomeClass {
  public UsingPattern SomeMethod() {
    Console.WriteLine("Zacatek bloku");
    return new UsingPattern(() => Console.WriteLine("Konec bloku"));
  }
}

public class OtherClass {
  public void Consumer() {
    var some = new SomeClass();

    using (some.SomeMethod()) {
      Console.WriteLine("Blok");
    }
  }
}

Tagy: ,

Blok using

19.33 - 28. července 2006 | Tuning

Jazyk C# je obdařen velice zajímavým blokem uvozený slovem using. Víte k čemu slouží? Používáte ho? Pokud jste si na jednu z předchozích otázek odpověděli negativně, měli byste si přečíst následující řádky. :)

Klíčové slovo using má v C# hned dva významy. Tím prvním je import namespaců a vytváření aliasů k třídám, ale ten je pravděpodobně provařený. Druhým významem je uvození bloku, ve kterém se používá komponenta implementující rozhranní IDisposable. Implementace IDisposable se používá k uvolňování zdrojů.

SqlConnection conn  = new SqlConnection(connString);
conn.Open();
// práce s databází
conn.Close();

To byla ukázka naivního přístupu k databázi, kdy se spoléháme, na to, že vše proběhne v pořádku a dojde k zavolání conn.Close(), což může být klidně pravda, ale pokud dojde k vyvolání jakékoli vyjímky před zavoláním conn.Close(), zůstane připojení stále otevřené, dokud nedojde k timeoutu a objekt conn nezpracuje GC. To může trvat hodně dlouho a zabírat tak zbytečně cenné systémové zdroje.

using (SqlConnection conn  = new SqlConnection(connString)) {
    conn.Open();
    // práce s databází
}

A takle by se to mělo psát. :) Blok using přijímá jako parametr disposovatelné komponenty a na konci bloku zavolá IDisposable.Dispose(). V případě SqlConnection volá metoda Dispose metodu Close. Nutno podotknout, že k zavolání metody Dispose dojde i při vyhození vyjímky. Jak je toho dosaženo? Blok using neni nic jiného než zkráceným (a pro mě i přehlednějším) zápisem následujícího kódu.

SqlConnection conn  = new SqlConnection(connString);
try {
    conn.Open();
    // práce s databází
}
finally {
    conn.Dispose();
}

Toť celé tajemství a kouzlo bloku using. Závěrem bych vám chtěl ještě doporučit blok using používat všude tam, kde používáte nejrůznější Readery, Writer a jiné třídy implemetující rozhranní IDisposable, protože tak můžete ušetřit cenné zdroje a zvýšit tak výkon vaší aplikace :) Hodně štěstí…