【发布时间】:2014-08-01 07:20:23
【问题描述】:
我已经实现了SqlClient 带有超时参数的连接功能。这意味着,connection.open() 在另一个线程中,并且在线程启动后,我正在检查经过的时间。如果时间已达到超时,则线程被中止并且不建立连接。
问题是,如果我的超时时间大于默认的connection.open() 超时时间,open() 会抛出SqlException,这不会在我的Catch(SqlException) 块中捕获。
我正在另一个线程中开始整个连接过程:
public void connect()
{
Thread connectThread = new Thread(waitForTimeout);
connectThread.Start();
}
连接线程 -> 启动另一个线程等待超时
public void waitForTimeout()
{
connection = new SqlConnection(connectString);
Thread timeoutThread = new Thread(openConnection);
timeoutThread.Start();
DateTime quitTime = DateTime.Now.AddMilliseconds(timeout);
while (DateTime.Now < quitTime)
{
if (connection.State == ConnectionState.Open)
{
transac = connection.BeginTransaction();
command = connection.CreateCommand();
command.Transaction = transac;
break;
}
}
if (connection.State != ConnectionState.Open)
timeoutThread.Interrupt();
}
这里的异常在 open() 默认超时后没有被捕获:
private void openConnection()
{
try
{
connection.Open();
}
catch(SqlException ex)
{
// This isn't caught anytime
}
}
感谢您的任何想法!
【问题讨论】:
-
这是一个糟糕的模式。
SqlConnection支持开箱即用的连接超时设置,您为什么要尝试以复杂且不起作用的方式做同样的事情?没有办法中止不在托管代码中的线程(甚至在托管代码中中止也是非常不受欢迎的)。更不用说Interrupt没有做你认为它做的事情。并且在一段时间内旋转 cpu 也是等待连接打开的一种愚蠢方式。SqlConnection甚至是线程安全的吗?我不这么认为... -
SqlConnection肯定不是线程安全的。跨线程共享它是一个非常糟糕的主意,并且肯定会给您带来麻烦。稍微偏离主题:使用 Tasks API 而不是直接使用线程。对于大多数用例而言,直接使用低级线程 API 已过时。 -
说真的,在一个问题上投入更多的线程很少有帮助。学习如何正确使用
SqlConnection,使用异步方法,了解多线程如何工作以及如何使用信号,处理同步等。多线程是一个非常复杂和复杂的问题,不是一个简单的解决方案阻塞问题。 -
我尝试将超时添加到连接字符串,但它不起作用。当然,我一直在寻找一些更清洁的解决方案。
Task也是问题,因为我应该让它与 .NET 3.5 一起使用。即使SqlConnection中的超时有效,由于连接时应用程序冻结,我需要在另一个线程中运行。
标签: c# sql-server multithreading sqlconnection sqlexception