私のwin8(winrt、c#)アプリケーションでは、非常に特殊な制限があるWebAPIを呼び出す必要があります。2秒ごとにWebサービスを呼び出す必要はありません。
私は次のようにこの制限を適用しようとしました:
class Client
{
const int Delay = 2000;
HttpClient m_client = new HttpClient();
int m_ticks = 0;
public async Task<string> Get(string url)
{
// Multiple threads could be calling, I need to protect access to m_ticks:
string result = null;
lock (this)
{
int ticks = Environment.TickCount - m_ticks;
if (ticks < Delay)
await Task.Delay(Delay - ticks);
result = await m_client.GetStringAsync(url);
m_ticks = Environment.TickCount;
}
return result;
}
}
これは私をレンガの壁にぶつけました:
- ロックでawaitステートメントを使用できません。
- Win8クライアントプロファイルに存在しないため、WebClient + Thread.Sleep(非同期ナンセンスを回避)のようなものにフォールバックすることはできません。
- このメソッドが「非同期」になるのを避けることはできません。非同期関数を使用しないと、GetStringAsyncまたはTask.Delayを待つことができないためです。
- 複数のスレッドがこの関数を呼び出している可能性があり、m_ticksへの同期アクセスが必要なため、ロックを回避することはできません。
いったいどうやってこのようなものを書こうと思うのでしょうか?