Asenkron bağlam yöneticisi, __aenter__ ve __aexit__ asenkron yöntemlerini tanımlayan bir nesnedir ve async with yapısında kullanılır. Bu yönetici, asenkron işlevlerde kaynakların doğru bir şekilde açılıp kapatılması için gereklidir: veritabanı bağlantıları, dosyalar, oturumlar vb.
Uygulama örneği:
class AsyncDBConnection: async def __aenter__(self): self.conn = await async_db_connect() return self.conn async def __aexit__(self, exc_type, exc, tb): await self.conn.close() async def main(): async with AsyncDBConnection() as conn: await conn.query('SELECT 1')
Asenkron bağlam, teknik gecikmelerle event loop'unu engellemeden, eşzamanlı programların verimliliğini artırır.
async defiçinde sıradanwithkullanmak mümkün mü?
Cevap: Evet, ama eğer bağlam yöneticisi içindeki işlemler awaitable (await gerektiriyorsa) asenkron with gereklidir. Sıradan with, asenkron giriş/çıkış desteği sunmaz, event loop'unu engeller veya giriş/çıkış içinde await çağrısı yapılırsa çökebilir.
Örnek:
async def foo(): with open('file.txt') as f: # bu tamam, okuma senkron data = f.read() # Ama sıradan bir bağlamda await kullanılamaz, sadece asenkron with içinde
Hikaye
Proje: Asenkron API'ye sahip web servisi.
Sorun: Veritabanı bağlantı yöneticisi sıradan
withkullanıyordu, ancak içindeawaitçağrılmıştı. Bu,RuntimeError("Cannot use 'await' outside async function")hatası ve prod'da event loop'unun blokajlarına yol açtı.
Hikaye
Proje: Websockets üzerinde sohbet uygulaması.
Sorun: Bağlantılarla çalışırken websocket kaynakları kapatılmadı (sıradan senkron yönetici kullanıldı), bu da bellek sızıntılarına ve askıda kalan bağlantılara neden oldu.
Hikaye
Proje: Çok iş parçacıklı asenkron görev kuyruğu.
Sorun: Görev yöneticisi
__aexit__yöntemini hatalı bir şekilde uyguladı, awaitable döndürmeyi unuttular. Bu nedenle görevlerin tamamlanması garanti edilmedi ve bazı görevler sistemde "askıda" kaldı.