DarioSantarelli.Blog("UgiDotNet");

<sharing mode=”On” users=”*” />
posts - 176, comments - 105, trackbacks - 3

My Links

News


This is my personal blog. These postings are provided "AS IS" with no warranties, and confer no rights.




Tag Cloud

Archives

Post Categories

My English Blog

LINQ to XML: "Halloween Problem"

Oggi, mentre mi stavo documentando su "LINQ to XML" (o XLINQ come preferite), mi sono imbattuto nel cosiddetto "Halloween Problem", un problema noto specialmente ai programmatori di database che, all'interno di una tabella, devono gestire il cambiamento della locazione fisica di un record a seguito di un UPDATE. Tale cambiamento infatti può generare talvolta una situazione di inconsistenza (e non di errore!!!) nel momento in cui lo stesso record viene rielaborato più volte all'interno del contesto di esecuzione di una singola operazione logica.
Ebbene, in "LINQ to XML" lo scenario da evitare è pressoché simile e si rileva spesso e volentieri nelle iterazioni.
Tutto nasce dal fatto che le iterazioni sulle collection tramite LINQ caratterizzano in effetti codice dichiarativo, in grado cioé di descrivere il risultato che vogliamo ottenere senza preoccuparci di "come" ottenerlo (compito che invece spetta al codice imperativo ottenibile ad esempio via API DOM o XPath).L'  "Halloween Problem" per LINQ to XML si verifica quindi in quelle manipolazioni di tipo imperativo che vanno a "mischiarsi" con query di tipo dichiarativo.
Ad esempio:

// Scatenerà una NullReferenceException !!!
foreach (var address in customers.Descendants("address")) address.Remove();

 
Il codice riportato scatenerà una eccezione di tipo NullReferenceException nel momento in cui tenterà di iterare l'oggetto address appena cancellato. In realtà questo non è solamente un problema di XLINQ: le stesse "framework design guidelines" ci invitano infatti a stoppare esplicitamente un' iterazione su una collection ogniqualvolta ne viene modificato un elemento (alcune classi .NET già "forzano" questo tipo di comportamento).
Il workaround di tutto questo è abbastanza intuitivo: creare una copia dei risultati della query utilizzando istruzioni come ToList() o ToArray(), implementando ovvero una sorta di caching che chiaramente implica un costo computazionale maggiore:

foreach (var address in customers.Descendants("address").ToList()) address.Remove();


E' necessario porre attenzione al fatto che non esiste per XLINQ un modo automatico per aggirare l' Halloween Problem, quindi occorre essere abbastanza "smaliziati" nel comprendere i possibili errori di esecuzione derivanti dalla non banalissima convergenza tra le caratteristiche dichiarative di XLINQ e le buon vecchie tecniche imperative di manipolazione di istanze XML, che possiamo ottenere ad esempio utilizzando le API DOM e XPath del framework.

Print | posted on lunedì 6 agosto 2007 17:05 | Filed Under [ .NET ]

Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET