Seltsames CLR/Compiler-Verhalten im Release-Modus, aber nicht im Debug-ModusC#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Seltsames CLR/Compiler-Verhalten im Release-Modus, aber nicht im Debug-Modus

Post by Anonymous »

Ich entwickle eine Anwendung für Windows CE und .NET Compact Framework 3.5.

Der Code läuft einwandfrei im Debug-Modus, aber wenn ich den Modus auf ändere Release Ich erhalte verschiedene Ausnahmen. Ich denke, es hängt mit einigen Optimierungen zusammen, die der Compiler im Release-Modus zu erreichen versucht, wie z. B. dem zu frühen Entsorgen und Garbage Collection eines Objekts.

Folgende Methode: Versuch, Entitäten in SQL einzufügen Kompakte Datenbank, wirft zwei Ausnahmen aus (ich denke, es ist zufällig):

Code: Select all

public int Add(List entities)
{
int rowsEffected = 0;
EntityMetadata metadata = GetMetadata();
using (SqlCeCommand command = new SqlCeCommand())
{
command.Connection = connection;
command.CommandType = CommandType.TableDirect;
command.CommandText = metadata.EntityMapAttribute.TableName;
SqlCeResultSet set = command.ExecuteResultSet(ResultSetOptions.Scrollable | ResultSetOptions.Updatable);

// Get generated Id, used in the loop below
command.CommandType = CommandType.Text;
command.CommandText = "SELECT @@IDENTITY";
foreach (var entity in entities)
{
SqlCeUpdatableRecord record = set.CreateRecord();
PropertyMetadata pkPropertyMetadata = null;
foreach (var prop in metadata.PropertyMetadataList)
{
if (prop.Attribute.IsPK)
{
// Identify PK Property, avoid setting values (db automatically sets id)
pkPropertyMetadata = prop;
}
else
{
object columnValue = prop.GetAccesssorDelegates().Getter(entity);
record.SetValue(prop.Attribute.ColumnNumber, columnValue);
}
}
set.Insert(record);

// Get Id of the inserted entity
if (pkPropertyMetadata != null)
{
object rawid = command.ExecuteScalar();
object convertedId = Convert.ChangeType(rawid, pkPropertyMetadata.Attribute.ColumnType, null);
pkPropertyMetadata.GetAccesssorDelegates().Setter(entity, convertedId);
}
rowsEffected++;
}
return rowsEffected;
}
}
Ausnahme 1:

Code: Select all

Test 'M:Babil04_Mobil.Tests.ORMTests.Engine_Works' failed: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
System.AccessViolationException: Attempted to read or write protected memory.  This is often an indication that other memory is corrupt.
at System.Data.SqlServerCe.NativeMethods.ExecuteQueryPlan(IntPtr pTx, IntPtr pQpServices, IntPtr pQpCommand, IntPtr pQpPlan, IntPtr prgBinding, Int32 cDbBinding, IntPtr pData, Int32& recordsAffected, ResultSetOptions& cursorCapabilities, IntPtr& pSeCursor, Int32& fIsBaseTableCursor, IntPtr pError)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommandText(IntPtr& pCursor, Boolean& isBaseTableCursor)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteScalar()
MORMEngine.cs(182,0): at MORM.MORMEngine.Add[T](List`1 entities)
Tests\ORMTests.cs(187,0): at Babil04_Mobil.Tests.ORMTests.Engine_Works()
Ausnahme 2:

Code: Select all

Test 'M:Babil04_Mobil.Tests.ORMTests.Can_Insert_Multiple' failed: Cannot access a disposed object.
Object name: 'SqlCeResultSet'.
System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'SqlCeResultSet'.
at System.Data.SqlServerCe.SqlCeResultSet.CreateRecord()
MORMEngine.cs(162,0): at MORM.MORMEngine.Add[T](List`1 entities)
Tests\ORMTests.cs(187,0): at Babil04_Mobil.Tests.ORMTests.Can_Insert_Multiple()
Der Komponententest, der die Methode aufruft, die eine Ausnahme auslöst:

Code: Select all

[Test]
public void Can_Insert_Multiple()
{
MORMEngine engine = new MORMEngine(connectionString);
engine.OpenConnection();

List inventories = new List();
for (int i = 0; i < 10000; i++)
{
inventories.Add(new TestInventory
{
Code = "test" + i
});
}

Stopwatch watch = new Stopwatch();
watch.Start();

int rows = engine.Add(inventories);

watch.Stop();
Console.WriteLine("Completed in {0} ms.", watch.ElapsedMilliseconds);
Assert.That(rows == 10000);
}
Erwartungen zufolge ist SqlCeResultSet bereits entsorgt. Weder rufe ich die Dispose()-Methode für das Objekt auf, noch setze ich sie auf null. Warum wird es entsorgt? Warum läuft es im Debug-Modus einwandfrei, aber nicht im Release-Modus?

Alle Ideen wären willkommen.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post