2011-02-08 2 views
8

Sono rimasto davvero affascinato dai contratti di codice introdotti in .NET 4 (anche se con l'aiuto di DevLabs). Ma una bella stampa mi ha raffreddato un po '. Ecco cosa dice:Contratti di codice - bello, al limite, ma non pronto per la prima serata?

  • Attualmente non vi è alcuna soluzione al problema quando le postcondizioni vengono richiamate al di fuori del blocco in un metodo thread-safe eccetto per non utilizzarle.
  • .NET si basa su un programma di reindirizzamento binario, rendendo così la costruzione più lenta.
  • L'utilizzo di contratti di codice può inoltre causare un problema di prestazioni in fase di esecuzione.
  • Non può essere utilizzato per i controlli di sicurezza perché possono essere aggirati in fase di esecuzione gestendo l'evento ContractFailed.

Il più grande per me è il primo. Non so se qualcuno scriva più app a thread singolo. Quindi se i contratti di codice non sono in grado di supportare il multithreading, non li vedo molto. O forse non dovrei sottolinearlo troppo perché le postcondizioni servono a far valere gli interni del metodo stesso, che può essere testato unitamente.

BTW, non ho trovato nulla e non ho provato a smontare il mio codice per vedere dove sono state iniettate le precondizioni. Suppongo in un metodo semplice quando lock() va per primo, è semplice iniettare i controlli subito dopo, ma con un metodo piuttosto complicato, quando il blocco avviene da qualche parte nel mezzo, potrebbe essere un problema. O se vengono utilizzati altri meccanismi diversi da lock().

risposta

3

Attualmente non vi è alcuna soluzione al problema quando le postcondizioni vengono chiamate al di fuori del blocco in un metodo thread-safe ad eccezione di non li usa.

Non proprio un problema: se si effettua un controllo all'esterno di un'istruzione di blocco in modalità thread-safe è possibile eseguire anche un problema. Regola la tua attuazione per questa piccola 'limitazione'. La domanda è: in che modo il rewriter del codice saprà che è necessario bloccare una risorsa? Penso che questa limitazione rimarrà per molto tempo.

.NET si basa su un programma di riscrittura binario, rendendo la costruzione più lenta.

Sì, alcuni IL devono essere valutati, generati e salvati per iniettare alcune nuove dipendenze di IL = più tempo ovviamente.

L'utilizzo di contratti di codice può inoltre comportare un calo delle prestazioni in fase di esecuzione.

Anche non insolito o un problema, più codice (generato per i contratti di codice) = più lento. Hai solo più codice in pratica e cosa potresti eseguire attraverso una classe proxy, quindi c'è più codice + possibile proxy.

Non può essere utilizzato per i controlli di sicurezza perché possono essere aggirati in fase di esecuzione gestendo l'evento ContractFailed.

Sì, non farlo. Non è nemmeno necessario smontare/rimontare il gruppo per saltare un potenziale controllo di sicurezza. Mantenere eventuali flussi di controllo relativi alla sicurezza sul server (sia esso web o db), se possibile, o cercare di offuscare il codice alla migliore abilità se locale.

8

Sembra che tu stia confondendo "scrivere app multi-threaded" con "rendere ogni classe thread-safe". Lasciando da parte il tricky question of defining the term "thread safety" suggerirei che solo poche delle tue classi dovrebbero usare il blocco nella maggior parte delle app.

In genere scrivo molte classi che non cercano di essere esplicitamente thread-safe, ma ugualmente non hanno alcuna dipendenza dal thread. Assumono che se li userai da più thread, lo farai solo da un thread alla volta, con le opportune barriere di memoria per assicurarti che le modifiche apportate in un thread siano visibili in qualunque thread le usi successivamente.

Non ci sono quindi relativamente pochi classi che svolgono il necessario coordinamento.

Ora, è possibile che i problemi con i Contratti di codice rendano queste poche classi sufficientemente deboli da far precipitare tutto il pensiero ... ma non darei per scontato che all'inizio.

Sono un po 'più preoccupato dei problemi che i Contratti di codice si troveranno ad affrontare con il compilatore C# facendo sempre più lavoro di riscrittura del codice ... Non so se il team di Contracts abbia già risolto problemi di blocchi iteratori, ma anche se lo fanno dovranno farlo di nuovo quando C# 5 esce con metodi asincroni ...

+0

Sono d'accordo quando si tratta di classi apolidi. Ma quando si tratta di gestire lo stato, le classi devono essere thread-safe. Faccio del mio meglio per minimizzare il numero di loro però. Sul lato, potrei pensare di più in bianco e nero o piuttosto tutto o niente approccio - perché usare i contratti di codice in alcuni punti e non in altri a causa dei loro limiti. – Schultz9999

+1

@ Schultz9999: No, solo le classi stateful * che vengono utilizzate simultaneamente da più thread * devono occuparsene. Va bene se * o * una classe viene utilizzata da un thread solo per un'intera richiesta (ad esempio, gli StringBuilder di solito non vengono utilizzati tra i thread) * o * vengono utilizzati solo da un thread alla volta, con opportune barriere di memoria per consistenza. Per quanto riguarda la tua seconda domanda: usa i contratti di codice solo per * alcuni * del tuo codice se così facendo rende il tuo codice più chiaro o più affidabile, in pratica. Alcuni codici sono difficili/impossibili da testare unitamente - ma scrivo ancora test dove posso ... è lo stesso qui. –

+0

Sono d'accordo con le tue risposte su come scrivere codice. Forse lo stesso oggetto di stato può fornire un modo per mantenere i thread interni sicuri, mentre i gestori potrebbero non preoccuparsi del blocco, consentendo in tal modo al rewriter di riorganizzare il codice come previsto. Questo aiuta a evitare il problema, ma rimane ancora. Accetterò l'altra risposta anche se mi piacciono entrambi i post ma hai infinitamente più punti :) – Schultz9999