На данный момент я испытываю очень неприятную проблему. Я попытаюсь отвлечь проблему, чтобы сделать ее немного легче. Он должен с сериализацией моего пользовательского объекта в базу данных в одном процессе и десериализации его в другом процессе.Deserializing memoryStream - неожиданное поведение
У меня есть два сборника; AppToDB.dll
и AppFromDB.dll
. У меня есть 3-я сборка - MyCustomObject.dll
- в которой обе эти сборки содержат ссылку. MyCustomObject.dll
распространяется MarshalByRefObject
.
В моей AppToDB.dll
я выполнить следующий код:
public bool serializeToDB(MyCustomObject obj)
{
OdbcDataAdapter da = new OdbcDataAdapter();
MemoryStream memStream = new MemoryStream();
try
{
ObjRef marshalledObj = RemotingServices.Marshal((System.MarshalByRefObject)obj);
// Serialize the object; construct the desired formatter
IFormatter oBFormatter = new BinaryFormatter();
// Try to serialize the object
oBFormatter.Serialize(memStream, marshalledObj);
// Create byte array
byte[] serialized = memStream.ToArray();
// Build the query to write to the database
string queryString =
"INSERT INTO MyCustomObject(id, object) VALUES(?, ?)";
OdbcCommand command = new OdbcCommand(queryString, connection);
command.Parameters.AddWithValue("id", 1);
command.Parameters.AddWithValue("object", serialized);
// Write the object byte array to the database
int num = command.ExecuteNonQuery();
}
catch { }
}
В AppFromDB.dll
я выполняю этот код:
public OCR.Batch deserializeFromDB()
{
MemoryStream memStream = new MemoryStream();
try
{
string queryString = "SELECT object FROM FCBatch";
OdbcCommand command = new OdbcCommand(queryString, connection);
OdbcDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess);
// Size of the BLOB buffer.
int bufferSize = 100;
// The BLOB byte[] buffer to be filled by GetBytes.
byte[] outByte = new byte[bufferSize];
// The bytes returned from GetBytes.
long retval;
// The starting position in the BLOB output.
long startIndex = 0;
MemoryStream dbStream = new MemoryStream();
while (reader.Read())
{
// Reset the starting byte for the new BLOB.
startIndex = 0;
// Read bytes into outByte[] and retain the number of bytes returned.
retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
// Continue while there are bytes beyond the size of the buffer.
while (retval == bufferSize)
{
dbStream.Write(outByte, 0, bufferSize);
dbStream.Flush();
// Reposition start index to end of last buffer and fill buffer.
startIndex += bufferSize;
retval = reader.GetBytes(0, startIndex, outByte, 0, bufferSize);
}
// Write the remaining buffer.
dbStream.Write(outByte, 0, (int)retval);
dbStream.Flush();
}
// Close the reader and the connection.
reader.Close();
dbStream.Position = 0;
object temp = oBFormatter.Deserialize(dbStream);
MyCustomObject obj = (MyCustomObject)temp;
return null;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
ОК, так что в обоих кусков кода вы можете увидеть MemoryStream
объект. В первом AppToDB
он создается, и если я смотрю его содержимое, он содержит 707 байт. Хорошо. Я пишу его в базу данных и сохраняю там как BLOB. Теперь в AppFromDB
Я извлекаю BLOB и сохраняю его в массиве byte[]
. Я снова напишу массив byte[]
на MemoryStream
и посмотрю, что мои объекты MemoryStream
содержат 707 байт, все из которых находятся на месте, как оригинал. Кажется, я успешно передал объект!
Теперь проблема заключается в object temp = oBFormatter.Deserialize(dbStream);
. Как только я попытаюсь десериализовать, мой object
является Прозрачным прокси, и я не могу отдать MyCustomObject
!! Как вернуть исходный объект? Как в # @ & 's имя у меня есть объект MemoryStream .... В памяти ... готов к сериализации ... и вдруг это Прозрачный прокси снова.
Я нахожусь в убытке. Помощь приветствуется. Я буду молиться, чтобы # @ & для того, кто имеет ответ;)
Edit 1 ОК, я должен сказать, вещи начинают иметь смысл сейчас (хотя проблема сохраняется). Моя проблема: у меня есть объект (включая состояние) с одной стороны, и мне нужно сохранить его в базе данных, поэтому я могу использовать его через несколько дней другим процессом с другой стороны.
Мой объект не является сериализуемым, поскольку он обертывает сторонний объект, который не помечен как сериализуемый. Поэтому мой единственный вариант, похоже, заключается в маршале, который возвращает ObjRef, который, в свою очередь, сериализуется. Но, конечно, через несколько дней - объект, который я десериализую, является просто ссылкой, и мой первоначальный объект ушел.
Как решить мою проблему? Все больше людей должно быть, сталкивались с этим, и я просто не могу найти ответ ...
Edit 2 Хорошо, я предполагаю, что я собираюсь написать свой собственные сериализации класса изоморфен объекту 3 партии. Затем пропустите весь сторонний объект и сохраните/заверните его информацию о состоянии и т. Д. Затем сериализуйте мой объект в базу данных ... Кажется, это единственный вариант.
Редактировать 3 Начиная с этой проблемы снова через некоторое время. Просто понял, что решение, опубликованное в Edit 2, не будет работать. Мне нужно десериализовать объект, который знает сторонняя сборка, поскольку он будет продолжать выполнять операции над ним.
возможно дубликат [Как маршал объекта и его содержимое (также объекты)] (http://stackoverflow.com/questions/3068702/how-to-marshal-an-object-and-its- content-also-objects) – Lucero