到Datastax C#驱动程序工程师:
C#驱动程序3.3.0在调用Connect()
时遇到死锁。 Windows窗体上的以下代码段将尝试连接死锁:
public void SimpleConnectTest()
{
const string ip = "127.0.0.1";
const string keyspace = "somekeyspace";
QueryOptions queryOptions = new QueryOptions();
queryOptions.SetConsistencyLevel(ConsistencyLevel.One);
Cluster cluster = Cluster.Builder()
.AddContactPoints(ip)
.WithQueryOptions(queryOptions)
.Build();
var cassandraSession = cluster.Connect(keyspace);
Assert.AreNotEqual(null, cassandraSession);
cluster.Dispose();
}
死锁发生在这里:
Cluster.cs ->
private void Init()
{
...
TaskHelper.WaitToComplete(_controlConnection.Init(), initialAbortTimeout);
...
}
我在本地机器上的Cassandra 3.9.0,CQL规范3.4.2上测试了这个。
此处调用此方法_controlConnection.Init()的所有内容都会死锁:
task = Id = 11, Status = WaitingForActivation, Method = "{null}", Result = "{Not yet computed}"
然后只运行30000ms并抛出:
throw new TimeoutException(
"Cluster initialization was aborted after timing out. This mechanism is put in place to" +
" avoid blocking the calling thread forever. This usually caused by a networking issue" +
" between the client driver instance and the cluster.", ex);
在3.2.0上运行相同的测试没有这样的问题。其他人可以测试一下吗?也许这恰好发生在我身上。
编辑:
以下是死锁的屏幕截图:
答案 0 :(得分:2)
感谢您的评论中的详细信息,我们能够确定潜在的问题。
Similar to what was proposed by Luke,有一些ConfigureAwait()
次来电失踪。
此问题会影响在Cluster.Connect()
环境中调用SynchonizationContext
的用户,这不是常见用例:
Connect()
之前)之前调用SynchonizationContext
以在所有表单中共享同一个Session实例。Connect()
的情况下)在任何端点操作之外调用SynchonizationContext
。请注意,此问题仅影响Connect()
次来电。其他阻止调用如Execute()
没有此问题。
在任何情况下,这个问题都可能是用户开始使用驱动程序的一个停顿,例如,用户创建一个简单的Windows窗体应用程序来尝试一个概念。
我已经提交了一个带有修复程序的pull请求,该请求还包含一个测试,该测试会查看使用await
而没有ConfigureAwait()
调用的源代码,以避免将来出现此问题:
https://github.com/datastax/csharp-driver/pull/309
您可以预期修复程序将在下一个修补程序版本中登陆。
答案 1 :(得分:1)
我无法重现此问题,但我怀疑问题可能出在recent change,以使连接过程在内部异步。我不确定,但通过Connect
代码进行追踪,我怀疑它可能缺少ConfigureAwait(false)
。特别是,它看起来像Reconnect
方法(它肯定会成为Init
代码路径的一部分)is missing one after that commit。我可能无法重现它,因为我没有按下Reconnect
代码路径,因为某些原因你在你的环境中。
我不是100%确定是罪魁祸首,但我opened a PR要解决它。 Stephen Cleary写了一篇关于为什么会在Forms / Web应用程序中发生这种情况的great explanation。您可以尝试从我的fork构建驱动程序,以查看该更改是否解决了问题,或者等待,看看PR和新版本会发生什么。如果它还在发生,我建议在JIRA上打开一个问题。
希望有所帮助!
答案 2 :(得分:0)
已在此处打开问题,解决方法:
https://datastax-oss.atlassian.net/projects/CSHARP/issues/CSHARP-579
对于任何遇到相同问题的人 - 只需将连接代码包装到新任务中即可。
Task.Run(() =>
{
SimpleConnectTest();
});