2017-09-13 3 views
3

この非同期aiohttpコードで何が問題になっていますか?次のコードを使用してaiohttpの場合

それは動作します
async def send(self, msg, url): 
    async with aiohttp.ClientSession() as session: 
     async with session.post(url, data=msg) as response: 
      self._msg = response.read() 

async def recv(self): 
    return await self._msg 

...時間のほとんどは、時折(しばしば、実際には)さまざまな例外で結果 - 通常切り捨て応答、または接続が既に閉じられた例外であること。これとは対照的に

、次のような作品完璧:

async def send(self, msg, url): 
    async with aiohttp.ClientSession() as session: 
     async with session.post(url, data=msg) as response: 
      self._msg = await response.read() 

async def recv(self): 
    return self._msg 

番目のバージョンは、私の目的のために技術的に間違っていると私はそれを修正する必要があるように私は、理由を知りたいです。 (応答が読み込まれる前にrecv関数が呼び出される可能性があるため、間違っています)

+0

"応答が読み込まれる前にrecv関数が呼び出される可能性があるため、間違っています" - caレスポンスが読み込まれる前に、最初のバージョンでは「待っていますか? 'self._msg'はまだ設定されていません。 – user2357112

+0

正確には、送信が完了した後も、私はちょうどrecvを呼び出すことはありません。しかし、ああ、それは本当に良い点です、それは*両方のバージョンが根本的に間違っていることが判明します。 「送信」と「recv」を概念的に分離したまま、修正案を提案できますか? – Arafangion

+0

(明確にする:修正を感謝しますが、実際の答えは2つのコードサンプルの違いを理解することです) – Arafangion

答えて

2

withはコンテキストマネージャーで、ブロック内のステートメントの前後にいくつかのコードを実行します。つまり、あなたの最初のrecv関数は、すでに閉じられている接続、またはこれらの行に沿ったものを参照する未来を待っている可能性が最も高いです。

のは、あなたがこのようになりますいくつかのコードを持っているとしましょう:

with open(...) as file: 
    file.read() 

これは大体、それが何をするかです:

file = open(...) 
file.read() 
file.close() 

そして、これがあなたの中でやっているのと同じです最初の例:

file = open() 
file.close() 
... 
file.read() 
+0

これは将来を無効にしますか? – Arafangion

+1

"未来を無効にする"ということはどういう意味なのか分かりませんが、基本的にはこのすべてが非同期問題ではありません。これは、クローズドソケットや 'response.read()'の深いところで起こっている何かからの読み込みの問題です。 –

+1

答えを更新しました。 –

関連する問題