Use using statement for IDisposable http objects
MODIFY
WalletWasabi.Tests/IntegrationTests/ExternalApiTests.cs
WalletWasabi.Tests/IntegrationTests/ExternalApiTests.cs
@@ -27,7 +27,7 @@ namespace WalletWasabi.Tests.IntegrationTests
public async Task SmartBitExchangeRateProviderTestAsync(string networkString)
{
var network = Network.GetNetwork(networkString);
- using var client = new SmartBitClient(network);
+ var client = new SmartBitClient(network);
var rateProvider = new SmartBitExchangeRateProvider(client);
IEnumerable<ExchangeRate> rates = await rateProvider.GetExchangeRateAsync();

MODIFY
WalletWasabi/WebClients/BlockchainInfo/BlockchainInfoExchangeRateProvider.cs
WalletWasabi/WebClients/BlockchainInfo/BlockchainInfoExchangeRateProvider.cs
@@ -25,8 +25,9 @@ namespace WalletWasabi.WebClients.BlockchainInfo
{
using var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://blockchain.info");
- var response = await httpClient.GetAsync("/ticker");
- var rates = await response.Content.ReadAsJsonAsync<BlockchainInfoExchangeRates>();
+ using var response = await httpClient.GetAsync("/ticker");
+ using var content = response.Content;
+ var rates = await content.ReadAsJsonAsync<BlockchainInfoExchangeRates>();
var exchangeRates = new List<ExchangeRate>
{

MODIFY
WalletWasabi/WebClients/Coinbase/CoinbaseExchangeRateProvider.cs
WalletWasabi/WebClients/Coinbase/CoinbaseExchangeRateProvider.cs
@@ -28,8 +28,9 @@ namespace WalletWasabi.WebClients.Coinbase
{
using var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://api.coinbase.com");
- var response = await httpClient.GetAsync("/v2/exchange-rates?currency=BTC");
- var wrapper = await response.Content.ReadAsJsonAsync<DataWrapper>();
+ using var response = await httpClient.GetAsync("/v2/exchange-rates?currency=BTC");
+ using var content = response.Content;
+ var wrapper = await content.ReadAsJsonAsync<DataWrapper>();
var exchangeRates = new List<ExchangeRate>
{

MODIFY
WalletWasabi/WebClients/ExchangeRateProviders.cs
WalletWasabi/WebClients/ExchangeRateProviders.cs
@@ -17,7 +17,7 @@ namespace WalletWasabi.WebClients
{
private readonly IExchangeRateProvider[] ExchangeRateProviders =
{
- new SmartBitExchangeRateProvider(new SmartBitClient(Network.Main, disposeHandler: true)),
+ new SmartBitExchangeRateProvider(new SmartBitClient(Network.Main)),
new BlockchainInfoExchangeRateProvider(),
new CoinbaseExchangeRateProvider(),
new GeminiExchangeRateProvider(),

MODIFY
WalletWasabi/WebClients/Gemini/GeminiExchangeRateProvider.cs
WalletWasabi/WebClients/Gemini/GeminiExchangeRateProvider.cs
@@ -18,8 +18,9 @@ namespace WalletWasabi.WebClients.Gemini
{
using var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://api.gemini.com");
- var response = await httpClient.GetAsync("/v1/pubticker/btcusd");
- var data = await response.Content.ReadAsJsonAsync<GeminiExchangeRateInfo>();
+ using var response = await httpClient.GetAsync("/v1/pubticker/btcusd");
+ using var content = response.Content;
+ var data = await content.ReadAsJsonAsync<GeminiExchangeRateInfo>();
var exchangeRates = new List<ExchangeRate>
{

MODIFY
WalletWasabi/WebClients/ItBit/ItBitExchangeRateProvider.cs
WalletWasabi/WebClients/ItBit/ItBitExchangeRateProvider.cs
@@ -18,8 +18,9 @@ namespace WalletWasabi.WebClients.ItBit
{
using var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri("https://api.itbit.com");
- var response = await httpClient.GetAsync("v1/markets/XBTUSD/ticker");
- var data = await response.Content.ReadAsJsonAsync<ItBitExchangeRateInfo>();
+ using var response = await httpClient.GetAsync("v1/markets/XBTUSD/ticker");
+ using var content = response.Content;
+ var data = await content.ReadAsJsonAsync<ItBitExchangeRateInfo>();
var exchangeRates = new List<ExchangeRate>
{

MODIFY
WalletWasabi/WebClients/SmartBit/SmartBitClient.cs
WalletWasabi/WebClients/SmartBit/SmartBitClient.cs
@@ -14,27 +14,23 @@ using WalletWasabi.WebClients.SmartBit.Models;
namespace WalletWasabi.WebClients.SmartBit
{
- public class SmartBitClient : IDisposable
+ public class SmartBitClient
{
public Network Network { get; }
- private HttpClient HttpClient { get; }
- public Uri BaseAddress => HttpClient.BaseAddress;
+ public Uri BaseAddress { get; }
private AsyncLock AsyncLock { get; } = new AsyncLock();
- public SmartBitClient(Network network, HttpMessageHandler handler = null, bool disposeHandler = false)
+ public SmartBitClient(Network network)
{
Network = network ?? throw new ArgumentNullException(nameof(network));
- HttpClient = handler != null
- ? new HttpClient(handler, disposeHandler)
- : new HttpClient();
if (network == Network.Main)
{
- HttpClient.BaseAddress = new Uri("https://api.smartbit.com.au/v1/");
+ BaseAddress = new Uri("https://api.smartbit.com.au/v1/");
}
else if (network == Network.TestNet)
{
- HttpClient.BaseAddress = new Uri("https://testnet-api.smartbit.com.au/v1/");
+ BaseAddress = new Uri("https://testnet-api.smartbit.com.au/v1/");
}
else
{
@@ -46,20 +42,23 @@ namespace WalletWasabi.WebClients.SmartBit
{
using (await AsyncLock.LockAsync(cancel))
{
- var content = new StringContent(
+ using var httpClient = CreateHttpClient();
+
+ using var content = new StringContent(
new JObject(new JProperty("hex", transaction.ToHex())).ToString(),
Encoding.UTF8,
"application/json");
- HttpResponseMessage response =
- await HttpClient.PostAsync("blockchain/pushtx", content, cancel);
+ using HttpResponseMessage response =
+ await httpClient.PostAsync("blockchain/pushtx", content, cancel);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpRequestException(response.StatusCode.ToString());
}
- string responseString = await response.Content.ReadAsStringAsync();
+ using var responseContent = response.Content;
+ string responseString = await responseContent.ReadAsStringAsync();
AssertSuccess(responseString);
}
}
@@ -67,15 +66,17 @@ namespace WalletWasabi.WebClients.SmartBit
public async Task<IEnumerable<SmartBitExchangeRate>> GetExchangeRatesAsync(CancellationToken cancel)
{
using (await AsyncLock.LockAsync(cancel))
- using (HttpResponseMessage response =
- await HttpClient.GetAsync("exchange-rates", HttpCompletionOption.ResponseContentRead, cancel))
{
+ using var httpClient = CreateHttpClient();
+
+ using var response = await httpClient.GetAsync("exchange-rates", HttpCompletionOption.ResponseContentRead, cancel);
if (response.StatusCode != HttpStatusCode.OK)
{
throw new HttpRequestException(response.StatusCode.ToString());
}
- string responseString = await response.Content.ReadAsStringAsync();
+ using var content = response.Content;
+ string responseString = await content.ReadAsStringAsync();
AssertSuccess(responseString);
var exchangeRates = JObject.Parse(responseString).Value<JArray>("exchange_rates");
@@ -97,36 +98,12 @@ namespace WalletWasabi.WebClients.SmartBit
}
}
- #region IDisposable Support
-
- private bool _disposedValue = false; // To detect redundant calls
-
- protected virtual void Dispose(bool disposing)
+ private HttpClient CreateHttpClient()
{
- if (!_disposedValue)
+ return new HttpClient()
{
- if (disposing)
- {
- // dispose managed state (managed objects).
- HttpClient?.Dispose();
+ BaseAddress = BaseAddress
+ };
}
-
- // free unmanaged resources (unmanaged objects) and override a finalizer below.
- // set large fields to null.
-
- _disposedValue = true;
- }
- }
-
- // This code added to correctly implement the disposable pattern.
- public void Dispose()
- {
- // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
- Dispose(true);
- // uncomment the following line if the finalizer is overridden above.
- // GC.SuppressFinalize(this);
- }
-
- #endregion IDisposable Support
}
}

Use using statement for IDisposable http objects