J'ai une opération asynchrone qui, pour diverses raisons, doit être déclenchée par un appel HTTP à une page Web ASP.NET. Lorsque ma page est demandée, elle doit lancer cette opération et renvoyer immédiatement un accusé de réception au client.
Cette méthode est également exposée via un service web WCF, et elle fonctionne parfaitement.
Lors de ma première tentative, une exception a été levée, me disant :
Asynchronous operations are not allowed in this context.
Page starting an asynchronous operation has to have the Async
attribute set to true and an asynchronous operation can only be
started on a page prior to PreRenderComplete event.
Alors bien sûr, j'ai ajouté le Async="true"
au paramètre @Page
directive. Maintenant, je ne reçois pas d'erreur, mais la page se bloque jusqu'à ce que l'opération asynchrone soit terminée.
Comment faire pour qu'une véritable page "fire-and-forget" fonctionne ?
Edit : Quelques codes pour plus d'informations. C'est un peu plus compliqué que ça, mais j'ai essayé d'y mettre l'idée générale.
public partial class SendMessagePage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string message = Request.QueryString["Message"];
string clientId = Request.QueryString["ClientId"];
AsyncMessageSender sender = new AsyncMessageSender(clientId, message);
sender.Start();
Response.Write("Success");
}
}
La classe AsyncMessageSender :
public class AsyncMessageSender
{
private BackgroundWorker backgroundWorker;
private string client;
private string msg;
public AsyncMessageSender(string clientId, string message)
{
this.client = clientId;
this.msg = message;
// setup background thread to listen
backgroundThread = new BackgroundWorker();
backgroundThread.WorkerSupportsCancellation = true;
backgroundThread.DoWork += new DoWorkEventHandler(backgroundThread_DoWork);
}
public void Start()
{
backgroundThread.RunWorkerAsync();
}
...
// after that it's pretty predictable
}