【发布时间】:2017-10-24 14:20:57
【问题描述】:
我实际上得到了各种 BinarySerializer 异常,例如:
- BinarySerializer.Serialize 异常:索引超出范围 数组。
- BinarySerializer.Serialize 异常:内部数组不能 扩展到大于 Int32.MaxValue 的元素。
- BinarySerializer.Serialize 异常:类型 'USC.GISResearchLab.Geocoding.Core.ReferenceDatasets.Sources.Implementations.Op enAddressPoints' 在大会 'Tamu.GeoInnovation.Geocoding.Core.ReferenceDatasets.FeatureSources, Version=1.0.0.0,Culture=neutral,PublicKeyToken=null' 未标记 作为可序列化的。
这里是被调用的方法:
try
{
string databaseName = ((IUserManagableBatchServiceManagableWebApplicationState)WebApplicationState).DatabaseManager.GetDatabaseNameFromGuid(databaseGuid);
int databaseId = ((IUserManagableBatchServiceManagableWebApplicationState)WebApplicationState).DatabaseManager.GetDatabaseIdFromGuid(databaseGuid);
string tableName = ((IUserManagableBatchServiceManagableWebApplicationState)WebApplicationState).DatabaseManager.GetTableNameFromGuid(tableGuid);
int tableId = ((IUserManagableBatchServiceManagableWebApplicationState)WebApplicationState).DatabaseManager.GetTableIdFromGuid(tableGuid);
int userId = ((IUserManagableWebApplicationState)WebApplicationState).UserManager.GetUserIdFromGuid(userGuid);
string sql = "";
sql += " INSERT INTO Processes ";
sql += " (";
...<many column and value fields here that should not be relevant to error>
sql += " )";
SqlCommand cmd = new SqlCommand(sql);
cmd.Parameters.Add(SqlParameterUtils.BuildSqlParameter("args", SqlDbType.VarBinary, BinarySerializer.Serialize(args)));
cmd.Parameters.Add(SqlParameterUtils.BuildSqlParameter("geocoderConfiguration", SqlDbType.VarBinary, BinarySerializer.Serialize(configuration)));
IQueryManager qm = WebApplicationState.QueryManager;
qm.AddParameters(cmd.Parameters);
qm.ExecuteNonQuery(CommandType.Text, cmd.CommandText, true);
}
catch (Exception ex)
{
string msg = "Error InsertProcess Method2: " + ex.Message;
throw new Exception(msg, ex);
}
}
我无法在本地重现该问题,并且经过相当长的调试时间后,无法找到所描述的任何问题。奇怪的是,在 IIS 中回收应用程序池解决了这个问题,并且该进程能够在没有错误的情况下启动。然后它稍后再次弹出,现在似乎更频繁地发生。除非我只是遗漏了一些东西,否则我无法在日志文件中找到任何相关的内容。我确信这对大多数人来说是一个显而易见的问题,但应用程序池绝对不是我的强项。如果有人可以为我指出正确的解决方案或更好的调试方向,将不胜感激。
这是 BinarySerializer 类:
public class BinarySerializer
{
public static byte[] Serialize(object o)
{
byte[] ret = null;
try
{
if (o != null)
{
if (o.GetType().IsSerializable)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(ms, o);
ret = ms.ToArray();
}
else
{
throw new Exception("BinarySerializer Exception: object is not serializable");
}
}
}
catch (Exception e)
{
throw new Exception("BinarySerializer.Serialize Exception: " + e.Message, e);
}
return ret;
}
【问题讨论】:
-
另一方面,您的所有错误都很清楚。首先 (3),您将无法序列化未标记为
[Serializable]的对象。 (2) - 你的对象对于int来说太长了。 (1) - 您试图访问不存在的数组索引。您是否尝试过真正调试您的代码?我可以告诉你很多——这不是游泳池问题。问题是您没有很好地测试您的应用程序。你从来没有经历过它在服务器上经历的“数据场景”。 -
我想这是令人困惑的部分。这个应用程序已经工作了好几年了,几乎没有什么变化。我很好奇您如何知道它在配置序列化程序中而不是在 args 中?我已经调试了很多次,这两个对象都没有问题,一切都很好。我可以一遍又一遍地运行相同的批处理过程而不会出现问题,然后突然在第 N 次运行时,我得到了上述错误之一。错误的不一致和零星性质以及回收池似乎解决了它的事实使我相信可能存在池问题。
-
该配置源自众多页面上的数十种方法,无法发布,因此缺少代码。考虑到完全相同的步骤,正在运行的相同文件仅偶尔会产生错误,这就是为什么我不认为这是配置问题。我还编辑了问题以包含 binaryserializer 类。
-
关闭大门,我可以告诉你那里有内存泄漏 - 你的内存流在使用后没有关闭
-
BinarySerializer 实际上是一个比我知识渊博的人早在我来到这里之前就编写的类。感谢您指出这一点,并且一定会在代码中搜索其余类以获取类似的泄漏。