Around and About .NET World

Il blog di Marco Minerva
posts - 1671, comments - 2232, trackbacks - 2135

My Links

News

Contattami su Live Messenger:


MCTS: Windows, Web, Distributed Applications & SQL Server

MCPD: Enterprise Applications

Tag Cloud

Archives

Post Categories

Links

Sapere quando è disponibile una connessione di rete

Il .NET Framework 2.0 offre due classi che consentono di sapere se una connessione di rete è disponibile e di ricevere notifiche quando lo stato della connessione cambia: si tratta rispettivamente di NetworkInterface e NetworkChange, entrambe contenute nel namespace System.Net.NetworkInformation. In particolare, NetworkChange è una classe statica che espone un metoodo di nome NetworkAvailabilityChanged, che viene generato quando lo stato della connessione cambia da non disponibile a disponibile, e viceversa.

Il problema di questa classe (se così si può chiamare) è che l'evento NetworkAvailabilityChanged viene generato in un thread secondario, quindi se si cerca di aggiornare l'interfaccia utente nell'handler di tale evento si ottiene un'eccezione causata dal tentativo di operazione cross-thread. Come è risaputo, in una situazione del genere è necessario utilizzare il metodo Invoke, così da garantire un accesso thread-safe ai controlli.

Come ho già scritto in questo post, è possibile evitare tale approccio utilizzando gli oggetti AsyncOperation e SendOrPostCallback. Non ci vuole molto per adattare il codice che avevo presentato in quell'occasione al nuovo contesto:

1 using System; 2 using System.ComponentModel; 3 using System.Threading; 4 5 namespace System.Net.NetworkInformation 6 { 7 public static class NetworkChange2 8 { 9 private static AsyncOperation operation; 10 private static SendOrPostCallback callback; 11 12 public static event NetworkAvailabilityChangedEventHandler 13 NetworkAvailabilityChanged; 14 15 static NetworkChange2() 16 { 17 callback = new SendOrPostCallback(Handler); 18 operation = AsyncOperationManager.CreateOperation(null); 19 NetworkChange.NetworkAvailabilityChanged += 20 new NetworkAvailabilityChangedEventHandler 21 (NetworkChange_NetworkAvailabilityChanged); 22 } 23 24 public static bool IsNetworkAvailable() 25 { 26 return NetworkInterface.GetIsNetworkAvailable(); 27 } 28 29 private static void NetworkChange_NetworkAvailabilityChanged 30 (object sender, NetworkAvailabilityEventArgs e) 31 { 32 operation.Post(callback, e); 33 } 34 35 private static void Handler(object stateInfo) 36 { 37 if (NetworkAvailabilityChanged != null) 38 NetworkAvailabilityChanged(null, 39 (NetworkAvailabilityEventArgs)stateInfo); 40 } 41 } 42 }

La classe NetworkChange2 non è altro che un wrapper per l'oggetto NetworkChange: quando quest'ultimo genera l'evento NetworkAvailabilityChanged, il suo gestore (righe 26-29) fa in modo di rilanciarlo all'interno del thread principale, attraverso il metodo Handler (righe 31-35).

L'utilizzo di questa nuova classe è immediato; è sufficiente cambiare le dichiarazioni come la seguente:

NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler (NetworkChange_NetworkAvailabilityChanged);

Utilizzando invece NetworkChange2:

NetworkChange2.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler (NetworkChange_NetworkAvailabilityChanged);

Fatto questo, all'interno del metodo NetworkChange_NetworkAvailabilityChanged sarà possibile accedere direttamente agli oggetti dell'interfaccia senza incorrere nell'errore InvalidOperationException.

Technorati tags: , ,

Print | posted on giovedì 27 dicembre 2007 02:39 | Filed Under [ C# ]

Feedback

Gravatar

# Determinare quando

Determinare quando
29/12/2007 16:31 | Around and About .NET World
Comments have been closed on this topic.

Powered by:
Powered By Subtext Powered By ASP.NET