【发布时间】:2023-03-08 19:10:01
【问题描述】:
我遇到了一个问题,我必须通过计划任务运行 C# 控制台应用程序。计划任务调用一个 Powershell 脚本,该脚本设置一些变量(如连接字符串)并调用一个 C# 控制台应用程序,该应用程序使用这些参数连接到数据库。
问题是,当计划任务由时间触发器触发时,我从日志中看到应用程序正常启动,尝试执行查询,但由于 SQl 超时而失败。
从计划任务窗口手动运行应用程序(右键单击>运行)可以正常运行,即使在自动运行失败后几秒钟也是如此。这种行为是如此一致(触发失败,手动运行),我不认为它是数据库。
这也不是启动目录、用户权限或参数差异,应用程序正在启动,只是在数据库访问失败。
此行为的原因可能是什么?我该如何补救?
任务的一些设置:
- 以最高权限运行:开启
- 无论用户是否登录都运行
- 不存储密码:关闭
- 用户帐号与登录用户相同
- 长时间运行时触发器未停止
- 启动目录和脚本位置正确(应用程序正在启动和记录,只是在数据库访问失败。手动右键单击>运行始终有效)
错误的堆栈跟踪:
System.Data.SqlClient.SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception (0x80004005): The wait operation timed out
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TrySetMetaData(_SqlMetaDataSet metaData, Boolean moreInfo)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
at System.Data.SqlClient.SqlDataReader.get_MetaData()
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader
感谢您的帮助!
【问题讨论】:
-
你的连接字符串是什么样的?考虑使用服务器的 IP 地址进行测试(如果您还没有这样做的话)。
-
我们使用的是 CNAME 记录,所以不是连接字符串中的实际 IP。我可以正常 ping 输入连接字符串中的服务器名称,并且它正常响应。连接字符串如下所示: Server=DBSERVER-NAME;database=databaseName;uid=username;pwd=password;PersistSecurityInfo=True;但它是(应该是?)使用手动运行的相同连接字符串作为触发,那么这会产生什么影响?但接下来我会尝试实际的 IP 地址
-
你的代码是什么样的? PowerShell 有一个 SQL 模块 (powershellgallery.com/packages/SqlServer) - 命令
Invoke-SqlCmd有一个参数QueryTimeout。 -
@GuentherSchmitz,谢谢,我知道。我已经拥有的应用程序,它不仅仅是查询数据库或执行一些 SQL。 Powershell 仅用作使用正确参数启动应用程序的驱动程序(其中一个参数是 Powershell 计算并提供给控制台应用程序的灵活日期)
标签: sql powershell scheduled-tasks