私は、ApiClient
クラスの複数のコンシューマによって同時に呼び出されるメソッドを持っています。最初のコールが完了してから残りのコールが短絡されるまで、メソッドへの同時呼び出しをブロックします。同時呼び出しをブロックし、非同期メソッドから単一の結果を返す
以下の擬似コードでは、複数のスレッドがRefreshApiTokenAsync()
を呼び出すことがあります。私は内部のthis.GetNewApiTokenAsync()
方法への単一の呼び出しを除いてすべてを防止したいと思う。これにより、コードが複数のスレッドで有効期限が切れたApiTokenを検出し、それを複数回リフレッシュしようとする状況が回避されます。
public class ApiClient
{
private static readonly ConcurrentDictionary<string, string> ApiTokens = new ConcurrentDictionary<string, string>();
public async Task DoSomething()
{
// Call third party API and then detect an out of date API token.
// The CallThirdPartyApi uses the token in the ApiTokens ConcurrentDictionary
var result = await CallThirdPartyApi();
if (result.ApiTokenOutOfDate) {
await this.RefreshApiTokenAsync();
result = await CallThirdPartyApi();
}
return result;
}
private async Task<string> RefreshApiTokenAsync()
{
string newToken = await this.GetNewApiTokenAsync();
return ApiTokens.AddOrUpdate("ApiToken", newToken, (key, value) => newToken);
}
}
私はこれがデバウンスと見なされると信じていますが、これを達成する方法がわかりません。
ですね()' ... – Malk
ロックが複数のスレッドを妨げますGetNewApiTokenAsyncを同時に呼び出すことはできませんが、最終的にはすべて呼び出されます。私が欲しいのは、GetNewApiTokenAsyncへの最初の呼び出しが行われることですが、実行中にメソッドを呼び出すための他の試みは、効果的に破棄されます。 –
'if(locked)return else else lockAndRun()' – Malk