2016-11-30 3 views
-1

Ich habe eine Kreuzgewindeoperation mit folgender Struktur.Abnormales Verhalten der Kreuzgewindeoperation

Die Anomalie ist, dass, wenn ich Haltepunkt bei Datensatz-Abfrage-Operation setzen, der Datensatz nicht null ist. Wenn ich jedoch den Haltepunkt entferne und das Programm ausführen lasse, ist der Datensatz immer Null. Ich habe sichergestellt, dass der Datensatzabruf korrekt ist. Ist das eine Art von Cross-Thread-Operation Anomalie? Hier

ist die invoke Verfahren

Invoke(new Action(() => 
    { 
     var filters = new KeyValuePair<string, object>[] 
      { 
      new KeyValuePair<string, object>("from_userid", ParentMessage.from_userid), 
      new KeyValuePair<string, object>("to_userid", this.SourceUser.id), 
      new KeyValuePair<string, object>("group_header_id", ParentMessage.group_header_id), 
      new KeyValuePair<string, object>("message", ParentMessage.message), 
      new KeyValuePair<string, object>("is_read", 0) 
      }; 

      MessagerLogModel MessageLog = null; 

      MessageLog = MessagerLogs.CustomFilter(filters).FirstOrDefault(); 


      if (MessageLog == null) 
      { 
       MessageBox.Show("message log model not found in database."); 
       return; 
      } 
})); 

Und hier ist der Betrieb Datenbank-Datensätze abzurufen.

public static List<MessagerLogModel> CustomFilter(KeyValuePair<string, object>[] _params) 
{ 
    var result = new List<MessagerLogModel>(); 

    string Query = @"SELECT * FROM messager_logs"; 

    List<MySqlParameter> commandParams = new List<MySqlParameter>(); 

    foreach (KeyValuePair<string, object> param in _params) 
    { 
     if (commandParams.Count == 0) 
      Query += " WHERE "; 
     else 
      Query += " AND "; 

     if (param.Value == DBNull.Value) 
      Query += param.Key + " IS @" + param.Key; 

     else 
      Query += param.Key + " = @" + param.Key; 


     commandParams.Add(new MySqlParameter("@" + param.Key, param.Value)); 
    } 

    MySqlDataReader r = 
     MySqlHelper.ExecuteReader(Shared.getConnectionString(), 
     Query, commandParams.ToArray()); 

    while (r.Read()) 
     result.Add(dataToModel(r)); 

    r.Close(); 

    return result; 
} 
+1

Das nennt man eine Race Condition. Sie müssen sicherstellen, dass der Wert im Hintergrund nicht geändert werden kann. Erstellen Sie beispielsweise eine Kopie. – SLaks

+0

Ich nahm an, dass alle diese Operationen innerhalb der 'Action'-Methode in einem einzigen Thread sind. Sollte der Code neben der Datenabfrage auf die Ausführung warten? –

+1

Das hängt davon ab, was 'Invoke()' tut. – SLaks

Antwort

3

Das Problem ist das "Lambda" in Ihrer Aktion. Sie fügen einige Werte hinzu: Sie werden nicht in den Lambda-Ausdruck zum Zeitpunkt der Lambda-Definition kopiert, sondern in dem Moment, in dem das Lambda ausgeführt wird. Mitgliedsvariablen wie ParentMessage.from_userid haben sich möglicherweise inzwischen geändert.