Ogni risorsa consumabile in Windows Phone e su qualsiasi piattaforma, viene in genere rappresentata da un URI, come ad esempio http://miosito/miarisorsa.txt, il quale si compone di varie parti:
- http: lo schema;
- la porta: 80 implicita per l'HTTP;
- miosito: il dominio;
- miarisorsa.txt: il path.
Facoltativamente si aggiungono poi la querystring e il fragment. Nel .NET Framework, e quindi anche in Windows Phone, quando si sfruttano le classi WebRequest o WebClient per scaricare una risorsa e proprio in virtù delle provenienza delle risorse, ogni schema determina il motore da utilizzare per ottenere una risposta: se HTTP occorre seguire un certo protocollo, se FTP un altro, se FILE invece occorre utilizzare le API di sistema, e così via.
E' possibile però registrare un proprio schema di propria invenzione, sia per implementare protocolli non supportati da Windows Phone, ma anche per aggiungere e centralizzare funzionalità aggiuntive da applicare ai protocolli già implementati. In questo script ad esempio si pone il semplice obiettivo di evitare, in modo centralizzato, di effettuare richieste HTTP in mancanza già a priori della rete internet, senza aspettare il timeout della richiesta.
In pratica, supponendo di inventare lo schema myhttp, quello che si vuole ottenere è poter scaricare la risorsa in questo modo:
WebClient client = new WebClient(); client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted); client.DownloadStringAsync(new Uri("myhttps://www.aspitalia.com"));
Per farlo occorre prima registrare il prefisso con il relativo oggetto responsabile della creazione delle richieste.
WebRequest.RegisterPrefix("myhttp", new AutoWebRequestCreator());
La classe AutoWebRequestCreator implementa l'interfaccia IWebRequestCreate e compie una semplice scelta: se internet è presente effettua la normale chiamata HTTP, mentre in caso contrario restituisce una fittizia implementazione di WebRequest che non esegue alcuna operazione.
public class AutoWebRequestCreator : IWebRequestCreate { public WebRequest Create(Uri uri) { // Internet è presente if (NetworkInterface.GetIsNetworkAvailable()) { // Restituisco una richiesta HTTP cambiando lo schema return WebRequest.CreateHttp(uri.ToString().Replace("myhttp://", "http://")); } else return new DummyWebRequest(); } }
La classe DummyWebRequest sovrascrive i metodi BeginGetResponse e EndGetResponse per restituire a loro volta un finto IAsyncResult, oggetto che rappresenta l'operazione asincrona.
public class DummyWebRequest : WebRequest { public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state) { // Risultato fittizio DummyAsyncResult ar = new DummyAsyncResult(state); // Chiamo subito il callback callback(ar); return ar; } public override WebResponse EndGetResponse(IAsyncResult asyncResult) { // L'operazione è stata cancellata throw new WebException("Cancelled", WebExceptionStatus.RequestCanceled); } }
Il DummyAsyncResult è invece implementato in modo da restituire costanti che indicano che l'operazione è già terminata.
public class DummyAsyncResult : IAsyncResult { public DummyAsyncResult(object state) { this.AsyncState = state; } public object AsyncState { get; private set; } public System.Threading.WaitHandle AsyncWaitHandle { get { return null; } } public bool CompletedSynchronously { get { return true; } } public bool IsCompleted { get { return true; } } }
I vantaggi che si ottengono con questo approccio sono molteplici. Per prima cosa si centralizzano una logica che, seppur semplice in questo esempio, è brutto e scomodo da replicare. Inoltre rende tutto piuttosto trasparente per quanto riguarda l'accesso alle risorse e infine permette di implementare scenari più evoluti. Ad esempio è possibile implementare una coda in modo da sequenzializzare le chiamate, oppure effettuare una cache sulle risorse web ed evitare di andare fisicamente sulla rete, recuperando il risultato dalla memoria o dall'isolated storage.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.
Approfondimenti
Evitare il flickering dei componenti nel prerender di Blazor 8
Gestire il colore CSS con HWB
Creare una libreria CSS universale: Clip-path
Le novità di Angular: i miglioramenti alla CLI
Utilizzare il nuovo modello GPT-4o con Azure OpenAI
Utilizzare QuickGrid di Blazor con Entity Framework
Potenziare Azure AI Search con la ricerca vettoriale
Generare token per autenicarsi sulle API di GitHub
Creare un webhook in Azure DevOps
Sostituire la GitHub Action di login su private registry
Creare alias per tipi generici e tuple in C#
Eseguire script pre e post esecuzione di un workflow di GitHub
I più letti di oggi
- Utilizzare il metodo CountBy di LINQ per semplificare raggruppamenti e i conteggi
- Effettuare il log delle chiamate a function di GPT in ASP.NET Web API
- Chiamare direttamente un numero di telefono con HTML5
- Richiamare programmaticamente le operazioni di aggiornamento, eliminazione e inserimento di FormView, DetailsView e GridView