Оптимизация запросов к Blockchain
Собственно, есть код на C#, задача которого - выкачивать решенные блоки и записывать в файл. Так как блоков достаточное количество - в приоритете скорость.
Сейчас делаю так:
Беру строку вида "https://blockchain.info/rawblock/{block_hash}"
Используя WebClient, и метод DownloadString - выкачиваю Json, такого вида:

На пикче не всё, для общего вида можете перейти: https://blockchain.info/rawblock/00000000000000000009a31ab0607a8814f084853bfd91668c98eb8f748f5083
Как для примера выглядел 5 блок: https://blockchain.info/rawblock/000000009b7262315dbf071787ad3656097b892abffd1f95a1a022f896f533fc
Расчленяю строку на необходимую информацию. Записываю в файл. Так же беру значение из next_block для следующего запроса.
Проблема в том, что на метод DownloadString тратиться колоссальное количество времени. И если вначале большая часть времени уходила на парсинг с помощью JsonConverter, то сейчас на скачивание строки Json. Хотел бы узнать, можно ли увеличить скорость. Выкачивая частично, или же используя другие методы/способы. (Связана ли скорость с несовершенством клиентского железа/интернет соединения, или же есть ограничения со стороны сервера. Насколько влияет конструкция try-catch в которую обернут метод.)
Жуть как сумбурно, но как есть. Заранее спасибо всем откликнувшимся.
Json не использую из-за скорости В GetRequest запрос в try и cathc ибо не всегда с первого раза срабатывает. Знаю, что косяк
namespace BlockchainAPI
{
public partial class MainWindow : Window
{
string path = @"E:\www.txt";
Stack<string> stack = new Stack<string>();
public MainWindow()
{
InitializeComponent();
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
//Чтение из файла последней записи, для получения next_block hash
string hash = await ParseLastHash();
//Запуск с актуальным hash
await Task.Run(() => GetData(hash));
}
#region Запрос с предыдущим hash для next_block
public async Task<string> ParseLastHash()
{
//Достаем из строки hash
string lastHashString = await GetLastHash();
string[] firstObj = lastHashString.Split('\t');
string hash = firstObj[3];
//Запрос для получения next_block hash
string s = await GetRequest(string.Format("https://blockchain.info/rawblock/{0}", hash));
string[] obj = s.Split('"');
//Возврат hash
hash = obj[21];
return hash;
}
#endregion
#region Чтение последней строки из файла
public async Task<string> GetLastHash()
{
try
{
using (StreamReader streamReader = new StreamReader(path, System.Text.Encoding.Default))
{
string previousLine = string.Empty;
string line = string.Empty;
while (true)
{
line = streamReader.ReadLine();
if (line == null)
{
return previousLine;
}
else
{
previousLine = line;
}
}
}
}
catch (Exception e)
{
Info.Text = Convert.ToString(e);
}
return "Exception";
}
#endregion
#region Запрос на сервер, с возвратом Json
public async Task<string> GetRequest(string address)
{
using (WebClient client = new WebClient())
{
try
{
return client.DownloadString(address);
}
catch
{
return client.DownloadString(address);
}
}
}
#endregion
#region Создание строки запроса. Запрос через GetRequest, расчленение результата
public async void GetData(string hash)
{
//Создание строки запроса
string address = string.Format("https://blockchain.info/rawblock/{0}", hash);
//Запрос и нарезка на массив стркок
string s = await GetRequest(address);
string[] obj = s.Split('"');
//Запись index
string index = obj[32];
index = index.Replace(":", string.Empty).Replace(",", string.Empty);
//Запись nonce
string nonce = obj[26];
nonce = nonce.Replace(":", string.Empty).Replace(",", string.Empty);
//Запись hash
string blockHash = obj[3];
//Запись next_block hash для следующего запроса
string nextBlock = obj[21];
//Добавление в stack форматированного текста
stack.Push($"index:\t{index}\thash:\t{blockHash}\tnonce:\t{nonce}");
//Запуск асинхронной записи
await Task.Run(() => Writing());
//Очистка
GC.Collect();
//Запрос с hash'ем следующего блока
GetData(nextBlock);
}
#endregion
#region Запись в файл
public async void Writing()
{
try
{
using (StreamWriter streamWriter = new StreamWriter(path, true, System.Text.Encoding.Default))
{
while (stack.Count != 0)
{
streamWriter.WriteLine(stack.Pop());
}
}
}
catch (Exception e)
{
Info.Text = Convert.ToString(e);
Console.WriteLine(e);
}
}
#endregion
}
}