超时异常导致SqlDataReader的关闭? [英] Timeout exception causes SqlDataReader to close?

查看:187
本文介绍了超时异常导致SqlDataReader的关闭?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从数据库中获取一些二进制数据,并将它们写入PDF文件。在大多数情况下,这是沿顺顺当当去,但数据的偶然行似乎抛出特定错误 -



超时过期。超时时间已过操作完成之前,或服务器没有响应。



请记住,这只是发生在行的屈指可数,而从来都不是随机的。相同的行总是抛出异常。我真的不知道为什么异常被抛出,但我确定有跳过那些造成问题,继续前进的行。我的问题,然而,就是当我赶上了异常,然后尝试移动到下一行,我碰到另一个例外 -



InvalidOperationException异常 - 无效试图调用读当读者是封闭的。



这是否意味着它运行读卡器就会自动关闭进入一个例外?我怎么会去继续到下一行没有任何戏剧?



 而(sdrReader.Read())//第二个异常这里发生的
{

{
字节[] = byteData新的字节[(sdrReader.GetBytes(0,0,NULL,0,int.MaxValue))]; //第一个例外发生在这里
sdrReader.GetBytes(0,0,byteData,0,byteData.Length);
串strOutputFileName = sdrReader.GetInt32(1)的ToString()+.PDF
msMemoryStreams =新的MemoryStream();
msMemoryStreams.Write(byteData,0,byteData.Length);
字节[]的字节数组= msMemoryStreams.ToArray();

msMemoryStreams.Flush();
msMemoryStreams.Close();

writeByteArrayToFile(byteData,txtFilesPath.Text +\\+ strOutputFileName);
}
赶上(例外五)
{
Logger.Write(文档无法转换:+ e.Message);
}
}



堆栈跟踪的要求 -

 在System.Data.SqlClient.SqlInternalConnection.OnError(SqlException异常,布尔breakConnection)
在System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning (TdsParserStateObject stateObj)
在System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj,UInt32的错误)
在System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult,TdsParserStateObject stateObj)
在System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
在System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
在System.Data.SqlClient.TdsParserStateObject.ReadByteArray(字节[] BUFF,偏移的Int32 ,的Int32 LEN)在System.Data.SqlClient.TdsParser.ReadSqlValue
(SqlBuffer值,SqlMetaDataPriv医师的Int32长度,TdsParserStateObject stateObj)
在System.Data.SqlClient.SqlDataReader.ReadColumnData()
。在System.Data.SqlClient.SqlDataReader.ReadColumn(我的Int32,布尔的setTimeout)
在System.Data.SqlClient.SqlDataReader.GetSqlBinary(我的Int32)
在System.Data.SqlClient.SqlDataReader.GetBytesInternal (我的Int32,Int64的dataIndex,字节[]缓冲区的Int32 bufferIndex,长的Int32)
在System.Data.SqlClient.SqlDataReader.GetBytes(我的Int32,Int64的dataIndex,字节[]缓冲区的Int32 bufferIndex,长的Int32)
在Pdf2Rtf.Form1.Read()在F:\Code\Pdf2Rtf\Pdf2Rtf\Pdf2Rtf\Form1.cs:在Pdf2Rtf.Form1.btnRead_Click线77
(对象发件人,EventArgs e)在F:\Code\Pdf2Rtf\Pdf2Rtf\Pdf2Rtf\Form1.cs:在System.Windows.Forms.Control.OnClick(EventArgs五)
。在系统24行
。 Windows.Forms.Button.OnClick(EventArgs五)
在System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
在System.Windows.Forms.Control.WmMouseUp(消息和;男,MouseButtons按钮,点击的Int32)在System.Windows.Forms.Control.WndProc(消息和
,M)
在System.Windows.Forms.ButtonBase.WndProc(消息和M)
在System.Windows.Forms.Button.WndProc(消息和M)
在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息和M)
在System.Windows.Forms.Control.ControlNativeWindow .WndProc(消息和M)
在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr的的HWND,味精的Int32,IntPtr的WPARAM,LPARAM的IntPtr)
在System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG和放大器; MSG)
在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(的Int32 dwComponentID,的Int32原因,的Int32 pvLoopData)
在System.Windows.Forms的。 Application.ThreadContext.RunMessageLoopInner(的Int32原因,ApplicationContext的情况下)
在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(的Int32原因,ApplicationContext的情况下)的System.Windows.Forms.Application.Run
(形式的MainForm)
在Pdf2Rtf.Program.Main()在F:\Code\Pdf2Rtf\Pdf2Rtf\Pdf2Rtf\Program.cs:行18
在System.AppDomain._nExecuteAssembly(大会装配,字串[] args)
在System.AppDomain.ExecuteAssembly(字符串assemblyFile,证据assemblySecurity,字串[] args)
在Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
。在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext中的ExecutionContext,ContextCallback回调,对象状态)在System.Threading.ThreadHelper.ThreadStart
()


解决方案

它看起来像你的的SqlCommand 已超时 - 当你调用的ExecuteReader ,相关命令仍然开放,将是脆弱的超时,直到你读完。因为它说在 SqlCommand.CommandTimeout 文档:




这属性是累计
超时期间所有网络读取
命令执行或处理
的结果。超时仍然会出现
返回的第一行后,和
不包括用户的处理时间,
只有网络读取时间。




在命令超时,它会关闭的读者,从中你无法恢复。



首先要试图解决这个是增加的CommandTimeout 显着,只是为了确保您可以继续。



接下来,如果你还没有这样做的话,它可以帮助使用的ExecuteReader 重载允许你指定一个的CommandBehavior ,并通过 CommandBehavior.SequentialAccess (每MSDN主题中推荐的检索大数据(ADO.NET))。



最后,你也可以尝试打破了读入的记录块。


I'm trying to pull some binary data from a database and write them to pdf files. For the most part, this is going along swimmingly, but the occasional row of data seems to throw a particular error -

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

Keep in mind, this only happens on a handful of rows, and is never random. The same rows always throw the exception. I'm not really sure why the exception is being thrown, but I'm ok with skipping the rows that do cause problems and move on. My problem, however, is that when I catch the exception and then try to move onto the next row, I run into another exception -

InvalidOperationException - Invalid attempt to call Read when reader is closed.

Does this mean the reader is automatically closing as soon as it runs into an exception? How would I go about proceeding to the next row without any dramas?

        while (sdrReader.Read()) // Second exception happens here
        {
            try
            {
                byte[] byteData = new Byte[(sdrReader.GetBytes(0, 0, null, 0, int.MaxValue))]; // first exception happens here
                sdrReader.GetBytes(0, 0, byteData, 0, byteData.Length);
                string strOutputFileName = sdrReader.GetInt32(1).ToString() + ".pdf";
                msMemoryStreams = new MemoryStream();
                msMemoryStreams.Write(byteData, 0, byteData.Length);
                byte[] byteArray = msMemoryStreams.ToArray();

                msMemoryStreams.Flush();
                msMemoryStreams.Close();

                writeByteArrayToFile(byteData, txtFilesPath.Text + "\\" + strOutputFileName);
            }
            catch (Exception e)
            {
                Logger.Write("Document failed to convert: " + e.Message);
            }
        }

Stack trace, as requested -

   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
   at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
   at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket()
   at System.Data.SqlClient.TdsParserStateObject.ReadBuffer()
   at System.Data.SqlClient.TdsParserStateObject.ReadByteArray(Byte[] buff, Int32 offset, Int32 len)
   at System.Data.SqlClient.TdsParser.ReadSqlValue(SqlBuffer value, SqlMetaDataPriv md, Int32 length, TdsParserStateObject stateObj)
   at System.Data.SqlClient.SqlDataReader.ReadColumnData()
   at System.Data.SqlClient.SqlDataReader.ReadColumn(Int32 i, Boolean setTimeout)
   at System.Data.SqlClient.SqlDataReader.GetSqlBinary(Int32 i)
   at System.Data.SqlClient.SqlDataReader.GetBytesInternal(Int32 i, Int64 dataIndex, Byte[] buffer, Int32 bufferIndex, Int32 length)
   at System.Data.SqlClient.SqlDataReader.GetBytes(Int32 i, Int64 dataIndex, Byte[] buffer, Int32 bufferIndex, Int32 length)
   at Pdf2Rtf.Form1.Read() in F:\Code\Pdf2Rtf\Pdf2Rtf\Pdf2Rtf\Form1.cs:line 77
   at Pdf2Rtf.Form1.btnRead_Click(Object sender, EventArgs e) in F:\Code\Pdf2Rtf\Pdf2Rtf\Pdf2Rtf\Form1.cs:line 24
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at Pdf2Rtf.Program.Main() in F:\Code\Pdf2Rtf\Pdf2Rtf\Pdf2Rtf\Program.cs:line 18
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

解决方案

It looks like your SqlCommand is timing out - when you call ExecuteReader, the associated command remains open and will be vulnerable to timeouts until you finish reading. As it says in the SqlCommand.CommandTimeout documentation:

This property is the cumulative time-out for all network reads during command execution or processing of the results. A time-out can still occur after the first row is returned, and does not include user processing time, only network read time.

When the command times out, it closes the reader, from which you can't recover.

The first thing to try to solve this is to increase the CommandTimeout dramatically, just to make sure you can proceed.

Next, if you haven't done so already, it may help to use the ExecuteReader overload that allows you to specify a CommandBehavior, and pass CommandBehavior.SequentialAccess (per the recommendation in the MSDN topic "Retrieving Large Data (ADO.NET)").

Finally, you might also try breaking the reads into chunks of records.

这篇关于超时异常导致SqlDataReader的关闭?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆