Итак, я пытаюсь создать простой механизм воспроизведения журналов для Solr.Это казалось достаточно простым, приложение формы Windows, содержащее цикл для чтения параметров запроса из файла журнала, восстановления URL запроса, отправки его с использованием HttpRequest (или WebClient).Конечно, я хотел бы, чтобы воспроизведение было максимально быстрым, поэтому каждый запрос запускается с собственным асинхронным делегатом.
Все работает просто отлично;Тем не менее, это не так быстро, как я ожидал.После некоторых копаний я узнал, что максимальное количество одновременных подключений ограничено: Улучшение производительности многопоточных запросов HttpWebRequest в .NET .Я внес соответствующие изменения в конфигурацию и попытался снова, но безуспешно.Независимо от того, как я стараюсь, мне кажется, что значение servicePoint.CurrentConnections будет больше 1.
Возможно, что-то еще я не учел?Чтобы быть конкретным: я использую фоновый рабочий объект в форме для запуска основного цикла (тот, который читает файл журнала).В этом цикле я вызываю мою асинхронную функцию BeginSearch, а она, в свою очередь, вызывает мой асинхронный обратный вызов EndSearch.
for (int i = 0; i < lines.Length - 1; i++)
{
//System.Diagnostics.Debug.WriteLine(lines[i]);
if ((urlParameters = this.GetURLParameters(lines[i])) != null)
{
//It looks like we have a logged query
Console.WriteLine(string.Format("{0} - {1}", servicePoint.ConnectionLimit, servicePoint.CurrentConnections));
//System.Threading.Tasks.Task<ServiceProviderResults> submitQuery = new System.Threading.Tasks.Task<ServiceProviderResults>(() => this.BeginSearch(urlParameters));
//System.Threading.Tasks.Task processQuery = submitQuery.ContinueWith(x => this.Y(x.Result));
//submitQuery.Start();
//Wait until the count of currently executing asynchronous operations falls below the predetermined threshold
while (this.currentAsyncOperations >= MAX_ASYNC_OPERATIONS)
{
System.Threading.Thread.Sleep(10);
}
lock (this.asyncLock)
{
this.currentAsyncOperations++;
}
SearchDelegate searchDelegate = new SearchDelegate(this.BeginSearch);
searchDelegate.BeginInvoke(urlParameters, new AsyncCallback(this.EndSearch), null);
//System.Threading.Thread.Sleep(0);
Application.DoEvents();
}
}
Асинхронный обратный вызов:
private ServiceProviderResults BeginSearch(string parameters)
{
QueryURL queryURL = new QueryURL(string.Format("{0}select?{1}", this.textBoxSolrCore.Text, parameters));
//TODO: For purposes of experimentation, overrides go here
return new ServiceProviderResults(queryURL);
}
Асинхронный обратный вызов:
{
ServiceProviderResults serviceProviderResults = null;
try
{
AsyncResult asyncResult = (AsyncResult)result;
SearchDelegate searchDelegate = (SearchDelegate)asyncResult.AsyncDelegate;
serviceProviderResults = searchDelegate.EndInvoke(result);
lock (statLock)
{
this.queriesCompleted++;
this.qTimeSum += serviceProviderResults.ResponseHeader.QTime;
this.roundTripSum += serviceProviderResults.Stopwatch.ElapsedMilliseconds;
}
string message = string.Format("NumFound: {0} QTime: {1}ms RoundTrip: {2}ms Query {3}", serviceProviderResults.NumFound, serviceProviderResults.ResponseHeader.QTime, serviceProviderResults.Stopwatch.ElapsedMilliseconds, serviceProviderResults.QueryURL.ToString());
//System.Diagnostics.Debug.WriteLine(message);
this.ShowProgress(message);
}
catch (Exception e)
{
this.exceptionsThrown++;
this.AddQueryException(new QueryException(e, serviceProviderResults.QueryURL));
}
finally
{
lock (this.asyncLock)
{
this.currentAsyncOperations--;
}
}
}