我在客户的服务器上遇到了一个奇怪的问题。不幸的是,无法在他们的环境中进行调试,并且在发送相同消息时,我无法在我们的服务器上重新创建问题。基本上,他们安装了两个程序:1) 检查电子邮件帐户是否有消息的 Windows 服务,以及 2) 在收到新消息时由 Windows 服务调用的 Web 服务。
Windows 服务使用下面的代码(方法 SaveToFileTable)使用文件流将文件保存在 SQL Server 中。保存文件后,它使用文件的主键调用 webservice,webservice 读取文件的内容并处理它。
问题
但发生的情况是,当我检查文件目录时,实际上创建了 2 个文件。首先是包含内容的正确文件,然后是一个空文件。市场服务器读取空文件并抛出异常。
问题
为什么文件流创建 2 个文件?根据下面的代码,首先创建一个空文件。然后给它一个 UNC 路径来获取这个空文件并写入它。不知何故有两个文件句柄?
附加信息
客户使用的是 SQL Server 2012,并且上面有两个实例。一种用于生产,一种用于测试。
private long SaveToFileTable(string fileContent)
{
using (SqlConnection con = new SqlConnection(m_constr))
{
con.Open();
using (SqlTransaction trn = con.BeginTransaction(System.Data.IsolationLevel.ReadCommitted))
{
StringBuilder sql = new StringBuilder();
sql.AppendLine("insert into Company.FileTable (FileData)");
sql.AppendLine("output inserted.FileIdentification, inserted.FileData.PathName() as Path, GET_FILESTREAM_TRANSACTION_CONTEXT() As TransactionContext");
sql.AppendLine("values(0x)"); //Empty binary value
byte[] fileData = System.Text.Encoding.UTF8.GetBytes(fileContent);
SqlCommand cmd = new SqlCommand(sql.ToString(),con, trn);
string path = null;
long fileId = 0;
byte[] context = null;
// cmd is an INSERT command that uses the OUTPUT clause
// Thus we use the ExecuteReader to get the
// result set from the output columns
using (SqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
fileId = rdr.GetInt64(0);
path = rdr.GetString(1);
context = rdr.GetSqlBytes(2).Buffer;
}
using (SqlFileStream sfs = new SqlFileStream(path, context, FileAccess.Write, FileOptions.SequentialScan, 0))
{
sfs.Write(fileData, 0, fileData.Length);
//file.InputStream.CopyTo(sfs);
}
trn.Commit();
return fileId;
}
}
}