Archive

Archive for the ‘C#’ Category

c#: Gestire un file di testo come risorsa

August 14th, 2010 Nicola No comments

Ecco un esempio di come creare in fase di sviluppo e di come leggere in fase di esecuzione un file di testo come risorsa all’interno dello stesso assembly.

Creare il Resources File:

- Creare un progetto di test con Visual Studio

- Impostare il nome dell’assembly ed il nome del namespace di default.

Assembly e Namespace di default

- Aggiungere al progetto un oggetto di tipo “Resources File”. Nel mio caso si chiama “license”

Oggetto di tipo Resources File

- Aggiungere al nuovo contenitore di risorse creato un nuovo file di testo. Nel mio esempio GPLlicense.txt

Text file in Resources File

Nel solution explorer compare il nuovo file (ed anche su filesystem).

New file in Solution Explorer

Leggere il file di testo dal Resources File a runtime

private void GetResourceFile(string nomeFile)
{
   try
   {
      System.Reflection.Assembly assembly;
      assembly = this.GetType().Assembly;
 
      ResourceManager resourceManager = 
                              new ResourceManager("Nicola.TestResources.license",
                                                              assembly);
 
      String s = resourceManager.GetString(nomeFile);
      Console.WriteLine(s.ToString());
   }
   catch (Exception e)
   {
      Console.WriteLine(e.Message);
   }
}

Il risultato:

Console output

Categories: C#, Programmazione Tags: ,

c#: Le unmanaged resource, l’interfaccia IDisposable e lo statement using

July 18th, 2010 Nicola No comments

Cosa sono le unmanaged resource: sono le risorse non gestite direttamente dal Garbace Collector. Due classici esempi sono i file e i font. La gestione di queste risorse è a carico del programmatore e può essere gestita attraverso i metodi Finalize and Dispose, per evitare memory leaks e risorse bloccate.

Cos’è l’interfaccia IDisposable: L’interfaccia IDisposable definisce un metodo (dispose) per il rilascio delle risorse allocate. L’implementazione di questa interfaccia in una unmanaged resource, permette di gestirne al meglio il ciclo di vita e la deallocazione di tutte le risorse coinvolte.

Cos’è lo statement using: using assicura che che gli oggetti IDisposable vengano usati correttamente. Ovvero, si assicura che venga sempre chiamato il metodo dispose() di un oggetto IDisposabile, anche in caso di eccezioni.

Ecco un classico esempio di utilizzo di using:

// Leggo una riga da un file di testo
string riga;
using (StreamReader reader = new StreamReader(@"c:\file.txt"))
{
   riga = reader.ReadLine();
}
 
// Scrivo una riga su file di testo:
using (StreamWriter myStream = new StreamWriter(_path, true))
{
   myStream.Write(sText);
}

Al termine di using non rimane nessuna traccia dell’oggetto reader instanziato, ed il suo metodo dispose() è stato chiamato. Ecco perchè using può essere usato solo con classi che implementano l’interfaccia IDisposable.

Ecco come può essere la gestione della scrittura di una stringa su file di testo inserendo using all’interno di un try/catch/finally:

String exception = "";
try {
   using (StreamWriter myStream = new StreamWriter(_path, true)) {
   myStream.Write(sText);
}
catch (IOException ioe) {
   exception = ioe.ToString();
}
...
...
...
catch (SecurityException se) {
   exception = se.ToString();
}
finally
{
   if (!"".Equals(exception)) Console.WriteLine(exception); }
}

Ecco un esempio di classe IDisposable e del relativo utilizzo di using:

public class Prova : IDisposable
{
   UnaMiaRisorsa risorsa;
   public Prova() {
   risorsa = new UnaMiaRisorsa(...);
   ...
   ...
   ...
 
   public void UtilizzaRisorsa() {
      // Utilizzo la mia risorsa
   }
 
   public void Dispose()
   {
      // Lasciamo libere le risorse. Ad esempio:
      UnaMiaRisorsa = null;
   }
}

Ed ecco come usiamo Prova

using (Prova prova = new Prova) {
   prova.UtilizzaRisorsa();
}

c#: PerformanceCounterCategory e PerformanceCounter per monitorare lo stato della memoria di un processo all’interno del CLR .NET

March 9th, 2010 Nicola No comments

Con queste classi è possibile monitorare molti aspetti vitali delle nostre applicazioni, come utilizzo di memoria, i/o sul disco ecc..
Questo link della Microsoft contiene molta documentazione interessante.

Il codice che segue analizza lo stato della memoria relativa un singolo processo,  corrispondente ad una applicazione .NET.

// Questa è l'area di cui vogliamo i contatori, ovvero ".NET CLR Memory"
System.Diagnostics.PerformanceCounterCategory area = 
   new System.Diagnostics.PerformanceCounterCategory(".NET CLR Memory");

Il seguente codice mostra a video tutte le istanze dentro l’area .NET CLR Memory analizzabili in quel momento sulla macchina:

string[] instanceNames;
 
instanceNames = mycat.GetInstanceNames();
for (int i=0; i < instanceNames.Length; i++)
{
   Console.WriteLine("Nome Istanza: {0}", instanceNames[i]);
}

Il suo output è simile a questo:

C:\Documents and Settings\colonnan\Documenti\Visual Studio 2008\Projects\Console
Application3\ConsoleApplication3\bin\Debug>MonitorProcesso.exe
Nome Istanza: <strong>MonitorProcesso</strong>
Nome Istanza: devenv
Nome Istanza: _Global_
Nome Istanza: MonitorProcesso.vshost

In questo esempio "MonitorProcesso.exe" è l’applicazione che sto lanciando, rappresentato dall’istanza "MonitorProcesso".
Per analizzare lo stato di memoria di MonitorProcesso.exe:

//Array dei contatori di un singolo processo.
System.Diagnostics.PerformanceCounter[] counters = 
   area.GetCounters("MonitorProcesso");
 
for (int i = 0; i < counters.Length;i++)
{
   Console.WriteLine("Performance counter: {0} = {1}", 
   counters[i].CounterName, counters[i].NextValue());
}

Il cui risultato è:

Performance counter: # Gen 0 Collections = 1
Performance counter: # Gen 1 Collections = 0
Performance counter: # Gen 2 Collections = 0
Performance counter: Promoted Memory from Gen 0 = 271400
Performance counter: Promoted Memory from Gen 1 = 0
Performance counter: Gen 0 Promoted Bytes/Sec = 0
Performance counter: Gen 1 Promoted Bytes/Sec = 0
Performance counter: Promoted Finalization-Memory from Gen 0 = 0
Performance counter: Promoted Finalization-Memory from Gen 1 = 1320
Performance counter: Gen 0 heap size = 524288
Performance counter: Gen 1 heap size = 524480
Performance counter: Gen 2 heap size = 12
Performance counter: Large Object Heap size = 541560
Performance counter: Finalization Survivors = 0
Performance counter: # GC Handles = 35
Performance counter: Allocated Bytes/sec = 0
Performance counter: # Induced GC = 0
Performance counter: % Time in GC = 1,227221
Performance counter: Not Displayed = 0
Performance counter: # Bytes in all Heaps = 1131064
Performance counter: # Total committed Bytes = 1662976
Performance counter: # Total reserved Bytes = 3,354624E+07
Performance counter: # of Pinned Objects = 0
Performance counter: # of Sink Blocks in use = 0

C# e SQL Server: INSERT, DateTime, OleDBCommand and Parameters

March 7th, 2010 Nicola No comments

Ecco un esempio di come utilizzare i Parameters all’interno di un oggetto OLEDBCommand.

La query

INSERT INTO TABELLA VALUES ('25/04/1972 10:40:00')

eseguita su un campo di tipo DATETIME si traduce grossolanamente in:

OleDbConnection conn;
OleDbCommand comando;

String connStr;
String sql;

connStr = @"Provider = SQLOLEDB.1;Password=" + password + ";User ID=" + user + ";Initial Catalog=" + database + ";Data Source=" + server;

conn = new OleDbConnection(connStr);
conn.Open();

sql = "INSERT INTO TABELLA VALUES ('25/04/1972 10:40:00')";
comando = new OleDbCommand(sql, conn);

comando.ExecuteNonQuery();

Può capitare che l’ultima istruzione dia errore, per problemi di sintatti del formato data. A seconda delle impostazioni predefinite del server il formato per la data può variare (ad esempio può essere ’1972-04-25 10:40:00).
L’utilizzo dei Parameters ovvia questa problematica. Ecco come diventa il codice:

DateTime dt = new DateTime(1972,4,25,10,40,0);
sql = "INSERT INTO TABELLA VALUES (?)";
comando = new OleDbCommand(sql, conn);
comando.Parameters.AddWithValue("@dataora", dt);

comando.ExecuteNonQuery();

Tutto qua.

c#: ReferenceEquals, Equals, Operatore ==

March 3rd, 2010 Nicola No comments
  • Il metodo ReferenceEquals verifica le uguaglianze per riferimento
  • Il metodo Equals verifica le uguaglianze per valore
  • l’operatore “==” a volte per riferimento e a volte per valore.

Ecco qualche esempio:

Se dichiariamo a e b in questo modo:

System.Object a = new System.Object();
System.Object b = a;

a e b sono riferimento allo stesso oggetto. Per avere la prova sul campo basta eseguire questo codice:

class Program
{
   static void Main(string[] args)
   {
      ObjectClass o1 = new ObjectClass();
      ObjectClass o2 = o1;
 
      o1.Value = 3;
      Console.WriteLine("o1: {0}", o1.Value);
      Console.WriteLine("o2: {0}", o2.Value);
      o2.Value = 5;
      Console.WriteLine("o1: {0}", o1.Value);
      Console.WriteLine("o2: {0}", o2.Value);</code>
 
      Console.WriteLine("ReferenceEquals: {0}", System.Object.ReferenceEquals(o1, o2));
   }
 
   class ObjectClass
   {
      private int value;</code>
 
      public int Value
      {
         get { return this.value; }
         set { this.value = value; }
      }
   }
}

Il risultato è:

o1: 3
o2: 3
o1: 5
o2: 5
ReferenceEquals: True
Equals: True
==: True

quindi modificare uno dei due oggetti significa modificare anche l’altro. Il metodo System.Object.ReferenceEquals verifica appunto l’uguaglianza per riferimento di due oggetti.

Se invece li dichiariamo così:

ObjectClass o1 = new ObjectClass();
ObjectClass o2 = new ObjectClass();

o1.Value = 3;
o2.Value = 3;
Console.WriteLine("ReferenceEquals: {0}", System.Object.ReferenceEquals(o1, o2));
Console.WriteLine("Equals: {0}", System.Object.Equals(o1, o2));
Console.WriteLine("==: {0}", o1 == o2);

il risultato è:

ReferenceEquals: False
Equals: False
==: False

  • ReferenceEquals è False perche o1 e o2 sono due oggetti separati, che nulla hanno in comune se non il valore uguale.
  • Equals è False perchè sto confrontando due oggetti che ho creato io, e in cui non ho specificato nessun ovverride per il metodo Equals.
  • == è false perchè in questo caso si comporta come ReferenceEquals

Un esempio interessante è questo, sulle stringhe:

String s1 = "pippo";
String s2 = "pippo";

Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals(s1, s2));
Console.WriteLine("Risultato Equals: {0}", System.Object.Equals(s1, s2));
Console.WriteLine("Risultato ==: {0}", s1 == s2);

il risultato è:

Risultato ReferenceEquals: True
Risultato Equals: True
Risultato ==: True

  • ReferenceEquals restituisce True perche s1 e s2 sono riferimento allo stesso oggetto. Così funziona c# quando si dichiarano più stringhe con lo stesso valore.
  • Equals resituisce True perchè sto confrontando un’oggetto con se stesso
  • == restituisce True perchè in questo caso si comporta come Equals

Invece:

String s1 = "pippo";
String s2 = String.Copy(s1);

Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals(s1, s2));
Console.WriteLine("Risultato Equals: {0}", System.Object.Equals(s1, s2));
Console.WriteLine("Risultato ==: {0}", s1 == s2);

(il metodo String.Copy crea una nuova istanza con valore uguale a quella in input)

genera questo risultato:

Risultato ReferenceEquals: False
Risultato Equals: True
Risultato ==: True

  • ReferenceEquals restituisce false, perchè s1 e s2 non puntano allo stesso oggetto
  • Equals restituisce True, perchè s1 e s2 hanno lo stesso valore
  • == restituisce True perchè in questo caso si comporta come Equals

L’operatore ==, al contrario del Java, può essere usato per il confronto fra stringhe. Ma vediamo cosa succede se facciamo un downgrade di String a Object:

String s1 = "pippo";
String s2 = String.Copy(s1);

Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals(s1, s2));
Console.WriteLine("Risultato ReferenceEquals: {0}", System.Object.ReferenceEquals((Object)s1, (Object)s2));

Console.WriteLine("Risultato Equals: {0}", System.Object.Equals(s1, s2));
Console.WriteLine("Risultato Equals: {0}", System.Object.Equals((Object)s1, (Object)s2));

Console.WriteLine("Risultato ==: {0}", s1 == s2);
Console.WriteLine("Risultato ==: {0}", (Object)s1 == (Object)s2);

Il risultato è:

Risultato ReferenceEquals: False
Risultato ReferenceEquals: False
Risultato Equals: True
Risultato Equals: True
Risultato ==: True
Risultato ==: False

Il suo comportamento è definito dall’msdn di mamma Microsoft:

For predefined value types, the equality operator (==) returns true if the values of its operands are equal, false otherwise. For reference types other than string, == returns true if its two operands refer to the same object. For the string type, == compares the values of the strings.

Ovvero: l’uguaglianza è verificata per valore se è verificata fra tipi predefiniti e stringhe, in tutti gli altri casi è per riferimento.

Categories: C#, Programmazione Tags: , ,