4 pagine in totale: <<Indietro 1 2 3 [4]
Un'applicazione di test utile...
Questo piccolo WinForm consente di selezionare i parametri di base e invoca la query LINQ. Siccome la chiamata al web service può avere una certa latenza, la query LINQ è eseguita su un worker thread in modo da consentire alla finestra dell'applicazione di processare altri messaggi, inclusa l'opzione di cancellare la richiesta.
Può essere un'ispirazione utile per chi vuole usare LINQ in un applicazione ma non vuole bloccare la UI mentre la query viene eseguita.
Per ottenere il comportamento asincrono desiderato, creeremo un metodo di tipo FormDelegate che processi una stringa contente l'HTML da presentare in un browser control.
private delegate void FormDelegate(string htmlSnippet);
private FormDelegate formDelegate;
private Thread currentThread = null;
private string queryTerm = null;
private string source = null;
private string cultureInfo = null;
private bool cancel = false;
public Form1()
{
InitializeComponent();
trident.Url = new Uri("about:blank");
sourceType.SelectedIndex = 0;
formDelegate = new FormDelegate(UpdateSearchResults);
}Il bello di avere un comportamento asincrono è che la UI resta attiva durante l'operazione, quindi la si può cancellare in qualunque momento.
private void button1_Click(object sender, EventArgs
{
if (!cancel)
{
cancel = !cancel;
button1.Text = "&Cancel";
queryTerm = queryTerms.Text;
source = sourceType.SelectedItem.ToString();
cultureInfo = cultureInformation.SelectedItem.ToString();
trident.Document.Window.Document.Body.InnerHtml = "Searching...";
PerformAsyncSearchRequest();
}
else
{
cancel = !cancel;
button1.Text = "&Execute";
trident.Document.Window.Document.Body.InnerHtml = "Searching
operation canceled";
currentThread.Abort();
}
}Questa funzione è il cuore dell'invocazione asincrona: gestisce il worker thread, abortendo l'operazione se ce n'è una già in corso o preparando il worker per eseguire il metodo che contiene la chiamata a LINQ
private void PerformAsyncSearchRequest()
{
if (currentThread != null && currentThread.IsAlive)
{
currentThread.Abort();
currentThread.Join();
}
currentThread = new Thread(new ThreadStart(ProcessSearchRequest));
currentThread.Start();
}Questa funzione incapsula la chiamata a LINQ e verrà eseguita da un thread diverso dal thread della UI. Di conseguenza, l'applicazione potrà continuare a processare messaggi mentre la query viene eseguita, mantnendo la chiamata alla query cancellabile dalla UI.
private void ProcessSearchRequest()
{
try
{
QueryableLiveSearchData<LinqSearchObject> LiveSearch = new
QueryableLiveSearchData<LinqSearchObject>();
var query = from result in LiveSearch
where result.QueryTerm == queryTerm &&
result.SourceSearch == source &&
result.CulInfo == cultureInfo
select new WebSearchResponse(result.Title,
result.Description, result.Url);
IAsyncResult r = BeginInvoke(formDelegate, DisplayResults(query));
}
catch (ThreadAbortException)
{
// Do Nothing.
}
}Questa è la funzione che il worker thread invoca quando ha eseguito la query ed i dati sono pronti per essere mostrati nella UI. Questa funzione viene eseguita dal UI thread attraverso la chiamata a BeginInvoke.
private string DisplayResults(IQueryable<WebSearchResponse> query)
{
string htmlSnippet = "<table><tr><th colspan='3'>Results:</th></tr>";
foreach (var q in query)
{
htmlSnippet += "<tr><td><a href='" + q.Url + "' target='_blank'>" +
q.Title + "</a></td><td colspan='2'>" + q.Description +
"</td></tr>";
}
htmlSnippet += "</table>";
return htmlSnippet;
}
public class WebSearchResponse
{
public string Title { get; set; }
public string Description { get; set; }
public string Url { get; set; }
public WebSearchResponse(string t, string d, string u)
{
Title = t;
Description = d;
Url = u;
}
}
Conclusioni
LINQ permette di estendere un potentissimo parser di espressioni per interagire con qualunque struttura che possa essere mappata in un oggetto.
In questo articolo, si è cercato di dare una chiave di lettura diversa per una caratteristica potentissima e rivoluzionaria che ha il potenziale per cambiare come tutti accediamo ai nostri dati.
Questo è un esempio abbastanza semplice, ma spero di avere messo in movimento molte idee, per altri servizi e data source nelle vostre applicazioni e nei vostri sistemi, che potrebbero giovare della semplicità e universalità di accesso offerta da LINQ.
La piccola applicazione di test può essere utilizzata come modello per qualunque form che voglia interrogare LINQ in modo asincrono. Non usatela su un server così com'è (la lunga serie di commenti all'articolo sulla concurrency di qualche settimana fa dovrebbe dare abbastanza spunti sul perchè)
Lo speciale completo su Visual Studio 2008, Windows Server 2008 e SQL Server 2008
- .NET Framework 3.5 e Visual Studio 2008: cosa c'è di nuovo di Riccardo Golia
- Le novità di C# 3.0 e Visual Basic 9.0 attraverso LINQ di Stefano Mostarda
- Introduzione a LINQ, LINQ to XML, Object e DataSet di Stefano Mostarda

- Introduzione ad ASP.NET 3.5: novità e caratteristiche di Daniele Bochicchio
- Introduzione ad ASP.NET 3.5 di Daniele Bochicchio

- Le novità di Communication e Workflow Foundation e la loro cooperazione nel .NET Framework 3.5 di Cristian Civera
- Windows Presentation Foundation 3.5: 3D interattivo e le altre novità del framework di Marco Leoncini
- Utilizzare Visual Studio 2008 per semplificare lo sviluppo con LINQ to SQL di Andrea Zani
- Uno sguardo a LINQ to SQL di Stefano Mostarda

- Le nuove caratteristiche di IIS 7.0 per sviluppatori e sistemisti di Daniele Bochicchio, Christian Paparelli
- Gestire transazioni miste con NTFS in Windows Server 2008 di Ugo Lattanzi
- LINQ oltre SQL e XML: creare un provider per l'integrazione con Live Search di Alessandro Catorcini
- Tracciare le modifiche ai dati e allineare i datawarehouse con il Change Data Capture in SQL Server 2008 di Luca Bianchi
4 pagine in totale: <<Indietro 1 2 3 [4]
Contenuti dell'articolo
- Pagina 1
- Pagina 2
- Pagina 3
- Pagina 4
Aggiungi un nuovo commento »»»
Per inserire un commento, devi registrarti alla nostra community.





Difficoltà

Stampa
Download 


