DotNet4Neo4j / Neo4jClient

.NET client binding for Neo4j
https://www.nuget.org/packages/Neo4jClient
Microsoft Public License
431 stars 146 forks source link

GraphClient.Connect() deadlock #157

Closed drgraduss closed 8 years ago

drgraduss commented 8 years ago

Hi,

I'm using GraphClient as part of topshelf win service. During deployment I'm experiencing deadlock when GraphClient.Connect() method called. Below is stack trace from dump.

mscorlib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout, bool exitContext)    Unknown
mscorlib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout)    Unknown
mscorlib.dll!System.Threading.ManualResetEventSlim.Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken)    Unknown
mscorlib.dll!System.Threading.Tasks.Task.WaitAllBlockingCore(System.Collections.Generic.List<System.Threading.Tasks.Task> tasks, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken)    Unknown
mscorlib.dll!System.Threading.Tasks.Task.WaitAll(System.Threading.Tasks.Task[] tasks, int millisecondsTimeout, System.Threading.CancellationToken cancellationToken)    Unknown
Neo4jClient.dll!Neo4jClient.Execution.ResponseBuilder.Execute(string commandDescription, System.Threading.Tasks.TaskFactory taskFactory)    Unknown
Neo4jClient.dll!Neo4jClient.Execution.ResponseBuilder<System.__Canon>.Execute()    Unknown
Neo4jClient.dll!Neo4jClient.GraphClient.Connect()    Unknown

After looking library code it looks there should be ConfigureAwait(false) setup on task returned in case taskFactory is null.

private Task<HttpResponseMessage> PrepareAsync(TaskFactory taskFactory)
{
    if (_executionConfiguration.UseJsonStreaming)
    {
        _request.Headers.Accept.Clear();
        _request.Headers.Remove("Accept");
        _request.Headers.Add("Accept", "application/json;stream=true");
        _request.Headers.Remove("X-Stream");
        _request.Headers.Add("X-Stream", "true");
    }

    _request.Headers.Add("User-Agent", _executionConfiguration.UserAgent);

    var userInfo = _request.RequestUri.UserInfo;
    if (!string.IsNullOrEmpty(userInfo))
    {
        var credentials = Convert.ToBase64String(Encoding.ASCII.GetBytes(userInfo));
        _request.Headers.Authorization = new AuthenticationHeaderValue("Basic", credentials);
    }

    if (taskFactory == null)
    {
        // use the standard factory
        return _executionConfiguration.HttpClient.SendAsync(_request);
    }

    // use a custom task factory
    return taskFactory.StartNew(() => _executionConfiguration.HttpClient.SendAsync(_request).Result);
}
cskardon commented 8 years ago

Hallo,

Do you feel up to doing a pull request? It'd be awesome to get that in place

drgraduss commented 8 years ago

Hi @cskardon

Here's pull request https://github.com/Readify/Neo4jClient/pull/158. Have a look as ExecuteAsync used across whole library.

cskardon commented 8 years ago

Awesome!! thank you, I'll get looking into it asap!