Paolo Pialorsi

SOA, Workflow Foundation (WF), Windows Communication Foundation (WCF) e le Architetture Distribuite

News

Archives

May 2004 - Posts

Best Practices Analyzer Tool for Microsoft SQL Server 2000 1.0

Un tool interessante sicuramente almeno da provare:

http://www.microsoft.com/downloads/details.aspx?FamilyID=b352eb1f-d3ca-44ee-893e-9e07339c1f22&DisplayLang=en

JWSDP 1.4: meglio tardi che mai :-) ...
Come si evince da questo comunicato stampa la prossima versione di JWSDP supporterà non solo WS-I BP1, ma anche WS-Security in versione OASIS ... che sia la volta buona per avere dei Web Service sicuri e interoperabili tra Java e .NET? ... Lo spero ardentemente!
Link: http://biz.yahoo.com/prnews/040527/sfth050_1.html
Professional InfoPath 2003: complimenti a Pierre!

Da poco più di un mese è nato un libro a proposito di uno dei prodotti che più apprezzo tra le novità introdotte da Office 2003: InfoPath!

I miei complimenti a Pierre Greborio che è uno dei due autori!


Link: http://www.wrox.com/books/0764557130.shtml
Articolo interessante su XmlSerializer

Ho appena visto che Christoph Schittko, un ragazzo molto in gamba che ho avuto il piacere di conoscere lo scorso anno ad ottobre a PDC, ha pubblicato su MSDN un articolo a proposito dei più comuni problemi legati allo sviluppo con XmlSerializer ... ovviamente con le soluzioni.

Bravo Christoph, ottimo articolo!

WSE2 Multimedia Content: update
Ho aggiunto il sorgente delle demo mostrate nei lab multimediali. Credo di aver fatto cosa gradita ...
Link: http://www.devleap.com/wse2/
MSDN Smart Client Developer Center
In effetti iniziavo a sentirne il bisogno ...
Link: http://msdn.microsoft.com/smartclient/
Windows SharePoint Services SDK Update

Hanno fatto qualche aggiornamento:

http://www.microsoft.com/downloads/details.aspx?familyid=1c64af62-c2e9-4ca3-a2a0-7d4319980011&displaylang=en

BizTalk Adapter per WSE2
Con un pizzico di soddisfazione ho appena scoperto che Scott Woodgate's ha annunciato il programma beta per un adapter BizTalk 2004 per WSE2. Il pizzico :-) di soddisfazione e soprattutto il piacere (da appassionato di BizTalk e di WSE2) è che a ottobre dello scorso anno avevo parlato, a PDC2003, con ScottW proprio a proposito di un adapter per WSE2 e ci eravamo poi sentiti con un paio di email per approfondire il perchè di una mia simile esigenza. Meno male! Evidentemente non ero il solo a desiderare un adapter simile :-) ! Inutile dire che non vedo l'ora di poterlo scaricare e provare ...
Link: http://blogs.msdn.com/scottwoo/archive/2004/05/24/140500.aspx
Visual Studio 2005 Community Technology Preview May 2004

E' disponibile su MSDN Subscribers download una nuova versione di VS.NET 2005. Se non la smettono di rilasciare nuove versioni ;-) di tutto ogni poco ... giuro che cambio lavoro :-D !!!

Ok ora sto "tentando" di scaricarlo ....


Link: http://msdn.microsoft.com/vs2005/
Materiale in inglese sull'utilizzo di WSE2
Buona visione ... sperando che il mio inglese non sia troppo "incomprensibile" :-) ...
Link: http://www.devleap.com/wse2/
WSE2 è nato!!!! Siiiiiiiii!!!!! :-)

Steve Ballmer nella sua keynote di oggi a TechEd ha annunciato il rilascio della versione finale di WSE2!!!

Ma vieniiiiiii!!!!! :-)

Le novità sono tante, soprattutto sul fronte del messaging e della gestione della sicurezza in modo pressoché "automatico".

State sintonizzati su questo canale ... a brevissimo arriverà del materiale utile a tal proposito!!!!

Birdge The Gap!


Link: http://msdn.microsoft.com/webservices/
WS-Trust e WS-SecureConversation

http://msdn.microsoft.com/webservices/understanding/specs/default.aspx?pull=/library/en-us/dnwebsrv/html/ws-trustandsecureconv.asp

Pattern & Practices per applicazioni SmartClient e SOA

In questi giorni sono stato impegnato in Microsoft per dei lab sullo sviluppo di SmartClient in architettura SOA. Molti dei ragazzi che hanno partecipato si sono dimostrati, almeno apparentemente :-), interessati ad alcuni Application Block e/o Application Guide.

Segnalo quindi volentieri alcuni link utili:

 

Lock o Monitor.Enter() ?

Ho letto un post di Andrea Zani, che ho avuto il piacere di conoscere qualche giorno fa, in cui espone il risultato di alcune verifiche che ha fatto con .NET Reflector per capire il comportamento di SyncLock di VB.NET e lock di C# rispetto all'uso autonomo e manuale di Monitor.Enter() ... Monitor.Exit(), in particolare nel caso in cui vi siano dei blocchi try..catch attorno al lock o al monitor del caso.

Rifaccio il discorso solo in C# e provo a darmi una risposta alla domanda che Andrea lascia aperta: "E' restata immutata, più veloce e più leggibile. Quali sono dunque le conclusioni di questo blog? Boh! Chi aveva ragione? Mah... :)":

using System;
using System.Threading;

public class TestLock
{

static Object test;

static void Main()
{
	test = new Object();
	usaLock();
	usaLockWithCatchBlock();
	usaMonitor();
	usaMonitorWithCatchBlock();
}

static void usaLock()
{
	lock(test)
	{
		Console.WriteLine("Faccio qualcosa...");
	}
}

static void usaMonitor()
{
	Monitor.Enter(test);
	try
	{
		Console.WriteLine("Faccio qualcosa...");
	}
	finally
	{
		Monitor.Exit(test);
	}
}

static void usaLockWithCatchBlock()
{
	try
	{
		lock(test)
		{
			Console.WriteLine("Faccio qualcosa...");
		}
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message);
	}
}

static void usaMonitorWithCatchBlock()
{
	try
	{
		Monitor.Enter(test);
		try
		{
			Console.WriteLine("Faccio qualcosa...");
		}
		finally
		{
			Monitor.Exit(test);
		}
	}
	catch (Exception ex)
	{
		Console.WriteLine(ex.Message);
	}

}

}

Il risultato analizzato con ILDASM (per fugare ogni dubbio relativo a qualche possibile fraintendimento di .NET Reflector) è il seguente:

.class public auto ansi beforefieldinit TestLock
       extends [mscorlib]System.Object
{
  .field private static object test
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       31 (0x1f)
    .maxstack  1
    IL_0000:  newobj     instance void [mscorlib]System.Object::.ctor()
    IL_0005:  stsfld     object TestLock::test
    IL_000a:  call       void TestLock::usaLock()
    IL_000f:  call       void TestLock::usaLockWithCatchBlock()
    IL_0014:  call       void TestLock::usaMonitor()
    IL_0019:  call       void TestLock::usaMonitorWithCatchBlock()
    IL_001e:  ret
  } // end of method TestLock::Main

  .method private hidebysig static void  usaLock() cil managed
  {
    // Code size       32 (0x20)
    .maxstack  2
    .locals init (object V_0)
    IL_0000:  ldsfld     object TestLock::test
    IL_0005:  dup
    IL_0006:  stloc.0
    IL_0007:  call       void [mscorlib]System.Threading.Monitor::Enter(object)
    .try
    {
      IL_000c:  ldstr      "Faccio qualcosa..."
      IL_0011:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_0016:  leave.s    IL_001f

    }  // end .try
    finally
    {
      IL_0018:  ldloc.0
      IL_0019:  call       void [mscorlib]System.Threading.Monitor::Exit(object)
      IL_001e:  endfinally
    }  // end handler
    IL_001f:  ret
  } // end of method TestLock::usaLock

  .method private hidebysig static void  usaMonitor() cil managed
  {
    // Code size       34 (0x22)
    .maxstack  1
    IL_0000:  ldsfld     object TestLock::test
    IL_0005:  call       void [mscorlib]System.Threading.Monitor::Enter(object)
    .try
    {
      IL_000a:  ldstr      "Faccio qualcosa..."
      IL_000f:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_0014:  leave.s    IL_0021

    }  // end .try
    finally
    {
      IL_0016:  ldsfld     object TestLock::test
      IL_001b:  call       void [mscorlib]System.Threading.Monitor::Exit(object)
      IL_0020:  endfinally
    }  // end handler
    IL_0021:  ret
  } // end of method TestLock::usaMonitor

  .method private hidebysig static void  usaLockWithCatchBlock() cil managed
  {
    // Code size       48 (0x30)
    .maxstack  2
    .locals init (class [mscorlib]System.Exception V_0,
             object V_1)
    .try
    {
      IL_0000:  ldsfld     object TestLock::test
      IL_0005:  dup
      IL_0006:  stloc.1
      IL_0007:  call       void [mscorlib]System.Threading.Monitor::Enter(object)
      .try
      {
        IL_000c:  ldstr      "Faccio qualcosa..."
        IL_0011:  call       void [mscorlib]System.Console::WriteLine(string)
        IL_0016:  leave.s    IL_001f

      }  // end .try
      finally
      {
        IL_0018:  ldloc.1
        IL_0019:  call       void [mscorlib]System.Threading.Monitor::Exit(object)
        IL_001e:  endfinally
      }  // end handler
      IL_001f:  leave.s    IL_002f

    }  // end .try
    catch [mscorlib]System.Exception 
    {
      IL_0021:  stloc.0
      IL_0022:  ldloc.0
      IL_0023:  callvirt   instance string [mscorlib]System.Exception::get_Message()
      IL_0028:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_002d:  leave.s    IL_002f

    }  // end handler
    IL_002f:  ret
  } // end of method TestLock::usaLockWithCatchBlock

  .method private hidebysig static void  usaMonitorWithCatchBlock() cil managed
  {
    // Code size       50 (0x32)
    .maxstack  2
    .locals init (class [mscorlib]System.Exception V_0)
    .try
    {
      IL_0000:  ldsfld     object TestLock::test
      IL_0005:  call       void [mscorlib]System.Threading.Monitor::Enter(object)
      .try
      {
        IL_000a:  ldstr      "Faccio qualcosa..."
        IL_000f:  call       void [mscorlib]System.Console::WriteLine(string)
        IL_0014:  leave.s    IL_0021

      }  // end .try
      finally
      {
        IL_0016:  ldsfld     object TestLock::test
        IL_001b:  call       void [mscorlib]System.Threading.Monitor::Exit(object)
        IL_0020:  endfinally
      }  // end handler
      IL_0021:  leave.s    IL_0031

    }  // end .try
    catch [mscorlib]System.Exception 
    {
      IL_0023:  stloc.0
      IL_0024:  ldloc.0
      IL_0025:  callvirt   instance string [mscorlib]System.Exception::get_Message()
      IL_002a:  call       void [mscorlib]System.Console::WriteLine(string)
      IL_002f:  leave.s    IL_0031

    }  // end handler
    IL_0031:  ret
  } // end of method TestLock::usaMonitorWithCatchBlock

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  1
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method TestLock::.ctor

} // end of class TestLock

Nei metodi privi di un try...catch loro si vede in modo chiaro che non c'è una reale differenza. Sì in effetti il caso basato su lock alloca uno stack maggiore, perchè viene dichiarata una variabile System.Object locale per contenere il riferimento all'oggetto statico sul quale faccio il lock. Nel caso di blocco try...catch con all'intero un lock o in alternativa un Monitor.Enter()...Monitor.Exit() non mi sembra però che ci sia differenza. Cioè il compilatore produce codice pressoché identico.
D'altra parte la soluzione del try...finally "secco" annidato in un try...catch esterno sappiamo essere generalmente migliore in quanto rilascia le risorse critiche prima della gestione dell'errore. Altrimenti il rischio è che, in situazioni in cui il blocco catch svolge attività impegnative (salvataggio di eventi su file o su eventlog, invio di email, ecc.) la nostra risorsa rimane impegnata inutilmente.
Quindi lock e SyncLock sono comodi e fanno la stessa cosa di Monitor.Enter()...Monitor.Exit(), a patto che se decidiamo di usare Monitor ci ricordiamo di costruire bene il codice, come di seguito ripetuto:

try
{
	Monitor.Enter(test);
	try
	{
		Console.WriteLine("Faccio qualcosa...");
	}
	finally
	{
		Monitor.Exit(test);
	}
}
catch (Exception ex)
{
	Console.WriteLine(ex.Message);
}

Evitiamo, in generale, situazioni come questa:

Monitor.Enter(test);
try
{
	Console.WriteLine("Faccio qualcosa...");
}
catch (Exception ex)
{
	Console.WriteLine(ex.Message);
}
finally
{
	Monitor.Exit(test);
}

In particolare se nel blocco catch svolgiamo attività impegnative e/o durature nel tempo.

Ancor peggio poi sarebbe una situazione come la seguente:

Monitor.Enter(test1);
Monitor.Enter(test2);
try
{
	Console.WriteLine("Faccio qualcosa...");
}
catch (Exception ex)
{
	Console.WriteLine(ex.Message);
}
finally
{
	Monitor.Exit(test2);
	Monitor.Exit(test1);
}

Ogni blocco Monitor.Enter()...Monitor.Exit() infatti deve avere un suo try...finally ad hoc. La soluzione corretta è quindi:

try
{
	Monitor.Enter(test1);
	try
	{
		Monitor.Enter(test2);
		try
		{
			Console.WriteLine("Faccio qualcosa...");
		}
		finally
		{
			Monitor.Exit(test2);
		}
	}
	finally
	{
		Monitor.Exit(test1);
	}
}
catch (Exception ex)
{
	Console.WriteLine(ex.Message);
}

Beh? Ma non sarebbe a 'sto punto meglio fare semplicemente:

try
{
	lock(test1)
	{
		lock(test2)
		{
			Console.WriteLine("Faccio qualcosa...");
		}
	}
}
catch (Exception ex)
{
	Console.WriteLine(ex.Message);
}

Ci sono ulteriori dettagli, da non sottovalutare, sul corretto e uguale ordine di applicazione dei lock in tutte le porzioni di codice, per evitare deadlock. Inoltre è molto opinabile il catch della Exception generica ... ma per tutte queste considerazioni c'è il libro di Marco Russo che è stato pubblicato apposta :-) !

A questo punto vorrei un parere anche dall'uomo CLR e multi-thread per eccellenza: Marco Russo. Marco hai 5 minuti per darci il tuo verdetto? :-)

WS-I Basic Security Profile

Leggo dal blog di Christian Weyer e segnalo volentieri anche io che WS-I ha rilasciato il WS-I Basic Security Profile Draft.

Bene bene .... dai che un po' alla volta si chiude il cerchio!


Link: http://www.ws-i.org/Profiles/BasicSecurityProfile-1.0-2004-05-12.html
More Posts Next page »