La classe
PostsBlogService contiene al suo interno il metodo
GetTitles(), che restituisce i titoli dei post:
....
public ViewStringModel GetTitles(string blog)
{ DoSleep();
string[] postBlog = new string[_titles.Length];
for (int i = 0; i < _titles.Length; i++)
postBlog<i> = blog + " " + _titles<i>;
return new ViewStringModel
{ PostsBlog = postBlog
};
}
public string[] GetTitlesBlog(string blog)
{ DoSleep();
string[] postBlog = new string[_titles.Length];
for (int i = 0; i < _titles.Length; i++)
postBlog<i> = blog + " " + _titles<i>;
return postBlog;
}
....</i></i></i></i>
Prima di proseguire con il codice della classe occorre creare la classe seguente, che servirà in seguito per gestire la sincronizzazione dei metodi asincroni:
public class StringArrayEventArgs : EventArgs
{ public string[] Value;
}
Si può riprendere ora il codice della classe
PostsBlogService con la dichiarazione di un evento, che intercetterà il termine dell'esecuzione del metodo asincrono; la classe
SyncCont fa uso di
System.Threading.SynchronizationContext e propaga un contesto di sincronizzazione. Nel metodo asincrono
GetTitlesAsync() si passa la stringa del blog alla classe
SynchronizationContext e a sua volta si istanzia un
Threading.Timer:
....
public event EventHandler<StringArrayEventArgs> GetTitlesCompleted;
class SyncCont
{ public SyncCont(SynchronizationContext scon, string Blog)
{ sc = scon; blog = Blog;
}
public SynchronizationContext sc { get; private set; } public String blog { get; private set; } }
public void GetTitlesAsync(string blog)
{ TimerCallback timerDelegate = new TimerCallback(HandleTimerCallback);
SyncCont rc = new SyncCont(SynchronizationContext.Current, blog);
Timer timer = new Timer(timerDelegate, rc, 0, Timeout.Infinite);
HttpContext.Current.Items[this] = timer;
}
private void HandleTimerCallback(object state)
{ SyncCont rc = (SyncCont)state;
SynchronizationContext syncContext = rc.sc;
syncContext.Send(FireEventSynchronously, rc.blog);
}
private void FireEventSynchronously(object state)
{ StringArrayEventArgs e = new StringArrayEventArgs()
{ Value = GetTitlesBlog((string)state)
};
OnGetTitlesCompleted(e);
}
private void OnGetTitlesCompleted(StringArrayEventArgs e)
{ EventHandler<StringArrayEventArgs> handler = GetTitlesCompleted;
if (handler != null)
{ handler(this, e);
}
}
public void GetTitlesAsync()
{ SynchronizationContext syncContext = SynchronizationContext.Current;
Timer timer = new Timer(state =>
syncContext.Send(d => OnGetTitlesCompleted(new StringArrayEventArgs()
{ Value = _titles
}), state),
null, 111, Timeout.Infinite);
HttpContext.Current.Items[this] = timer;
}
}
}
Il suddetto
OnGetTitlesCompleted() è un metodo che contiene la notifica dell'avvenuto completamento di
GetTitleAsync().