Tâche asynchrone dans l'asp .net MVC 5
Je suis en train d'utiliser asynchrone, attendent et tâche de mettre en œuvre une asynchrone exigence dans mon application web. J'ai code ci-dessous dans ma classe de contrôleur. Ce que je veux, c'est qu'après l'écoulement atteint à l'impression de "contrôleur 1", le système commence la méthode des affaires sur un thread séparé et sans attendre la réponse du système doit atteindre pour imprimer la déclaration de contrôleur et de l'imprimé "contrôleur 2". Mais quand je suis à l'exécution du code ci-dessous, je suis sortie motif que ce-
controller 1
PlandesignBS
controller 2
Alors que je m'attends à ce que ce-
controller 1
controller 2 (Flow should reach here immediately rather than waiting
for business methods to get executed First)
Contolleur De Classe Code-
public class PlanDetailsController : Controller
{
[HttpPost]
public async Task<ActionResult> Generate(PlanDetailsVM planDetailsVM)
{
System.Diagnostics.Debug.WriteLine("controller 1");
//calls business method to generate
quoteId = await Task.Run(() => _planDesignBS.GenerateBS(planDetailsVM));
System.Diagnostics.Debug.WriteLine("controller 2");
return Json(quoteId , JsonRequestBehavior.AllowGet);
}
}
D'Entreprise Le Code De La Méthode-
public int GenerateBS(PandetailsDTO plandetails)
{
System.Diagnostics.Debug.WriteLine("PlandesignBS");
//STEP 1-> call to dataLogic Layer to use Entity Framework
//STEP 2-> call to a method (this method is part of dll used
//in our project and we don't have any control on it)
return quoteId
}
EDIT: La raison pour laquelle je suis en train de faire c'est que je veux utiliser quelques http Postes de demandes de mon côté client. Supposons que j'appelle la génération de l'action d'abord la méthode de mon côté client et ensuite ne voulez pas attendre la réponse de celle-ci et dans le même temps vouloir invoquer un autre post http.
EDIT: y Compris EF code où je suis execption quand je suis en train de suivre quelques solutions.Cette méthode sera appelée à partir de mon GenerateBS méthode. Je suis d'exception sur cette ligne à l'intérieur de getSICCode méthode-
DbContext.Database.ExecuteSqlCommand("spGET_SICCode @industryClasifID,@industrySubClasifID,@SICCode OUTPUT", industryClasifID, industrySubClasifID, SICCode);
EF Code-
public class PlanDesignRepository : Repository<myobject>, IPlanDesignRepository
{
private IDbSet<myobject> _dbSet;
private DbContext _dbContext;
private IDbSet<myobject> DbSet
{
get
{
if (_dbSet == null)
{
_dbSet = base.UnitOfWork.Context.Set<myobject>();
}
return _dbSet;
}
}
private DbContext DbContext
{
get
{
if (_dbContext == null)
{
_dbContext = base.UnitOfWork.Context;
}
return _dbContext;
}
}
public string GetSICCode(IndustryClassficDO industryClassficDO)
{
SqlParameter industryClasifID = new SqlParameter("industryClasifID", SqlDbType.Int);
industryClasifID.Value = industryClassficDO.IndustryClassificationId;
SqlParameter industrySubClasifID = new SqlParameter("industrySubClasifID", SqlDbType.Int);
industrySubClasifID.Value = industryClassficDO.IndustrySubClassificationId;
SqlParameter SICCode = new SqlParameter("SICCode", SqlDbType.VarChar, 10);
SICCode.Direction = ParameterDirection.Output;
DbContext.Database.ExecuteSqlCommand("spGET_SICCode @industryClasifID,@industrySubClasifID,@SICCode OUTPUT", industryClasifID, industrySubClasifID, SICCode);
return (string)(SICCode.Value);
}
}
EDIT: j'ai quelques Post http appels comme indiqué ci-dessous-
AngularJS code for AJAX calls:
$http({
url: key_Url_Generate,
method: Post,
params: $scope.PlanDetails
}).then(function (result) {
//Notify user for success or failure
}
Que dois-je faire pour les Éliminer?
Vous devez appeler la méthode dispose, mais je ne suis pas en train de vous dire de la Jeter, je me demande où vous Disposer parce que l'exception que vous rapport dit que la méthode dispose a appelés, mais peu de code a essayé d'utilisation de l'objet par la suite.
Je ne suis pas familier avec anguleux, mais cela ressemble à une seule demande. Si vous n'deux $http(...) les appels doivent être envoyés simultanément. Assurez-vous de ne pas ajouter le deuxième appel à la fonction de rappel (puis de la fonction)
ouais, mais je ne sais pas pourquoi il ne fonctionne pas pour moi. Je vais essayer ce que résout mon problème de savoir si la modification du code dans code côté client ou du côté serveur de code.
OriginalL'auteur Anil kumar | 2015-02-22
Vous devez vous connecter pour publier un commentaire.
L'utilisation de l'attendent signifie que vous êtes en attente pour la tâche à accomplir avant de poursuivre le code. Si vous souhaitez exécuter simultanément avec l'autre code, vous devez le modifier comme ceci
Cependant, je ne recommanderais pas ce que cela ne sert à rien et peut dégrader les performances par mourir de faim la ASP.NET thread pool de threads. Pourquoi voulez-vous faire cela de toute façon?
Je ne sais pas où vous créez ou de Céder votre contexte, de sorte que je ne peux pas aider, sauf si vous fournissez ce code. Cependant j'ai encore besoin de vous demander quel est votre objectif final. Qu'espérez-vous réaliser?
La raison pour laquelle je suis en train de faire c'est que je veux utiliser quelques http Postes de demandes de mon côté client. Je tiens à appeler l'produire de l'action d'abord la méthode de mon côté client et ensuite ne voulez pas attendre la réponse de celle-ci et dans le même temps vouloir invoquer un autre post http. Je vais essayer d'inclure le EF code bien dans ma question.
Si vous avez besoin d'incendie 2 requêtes AJAX avec votre code JavaScript coté client. Pourquoi avez-vous besoin async code sur le serveur?
Parce que ma première requête AJAX ne permet pas à mon autre requête AJAX pour envoyer une réponse à moins que l'exécution terminée.
OriginalL'auteur Stilgar
Cette ligne:
unde façon synchrone attend pour l'appeler à l'intérieur de
Task.Run
pour terminer. C'est pourquoi vous voyez"PlandesignBS"
imprimé et seulement après que vous voyez à l'appel de la manette 2.Si vous souhaitez émettre un "fire and forget" style d'exécution, vous ne veux pas attendre à tout.
Vous ne devez surtout pas utiliser
Task.Run
à l'intérieur ASP.NET à tous, comme c'est dangereux. Au lieu de cela, si vous êtes sur .NET 4.5.2 et au-dessus, vous pouvez utiliserHostingEnvironment.QueueBackgroundWorkItem
ou si pas, vous pouvez utiliserBackgroundTaskManager
par Stephan Cleary, qui en toute sécurité enregistre le thread d'arrière-plan avec l'application de la piscine, de sorte que votre thread n'a pas interrompu une fois une re-cycle est appelé:Comme une note de côté, Si vous êtes d'appel d'Entity Framework, il n'y a normalement pas besoin d'impliquer d'autres threads. La Version 6 et supérieure expose APPUYEZ asynchrone en fonction de l'API qui sont
Task
de retour que vous pouvez utiliser à votre disposition pour faire ce genre de IO en fonction des requêtes.Oui, vous pouvez manuellement créer votre propre mise en œuvre, par la mise en œuvre de
IRegisteredObject
interface. Ici c'est une simple promenade à travers ce qui peut vous obtenir a commencé. Aussi, vous pouvez regarder à la mise en œuvre deBackgroundTaskManager
J'ai essayé d'utiliser BackgroundTaskManager mais j'ai reçu un EF liées exception. J'ai inclus les détails en Question. Merci de voir si vous pouvez aider.
Quel est le message de l'exception?
Exception est "L'opération ne peut pas être réalisée car le DbContext a été éliminé"
OriginalL'auteur Yuval Itzchakov
Le problème, c'est que vous ne peut tout simplement pas d'expédition code asynchrone qui tombent de la asp.net demande de pipeline en soi.
De la fonctionnalité async dans asp.net MVC seulement d'améliorer la gestion interne des threads à l'intérieur du processus IIS. Il ne vous permet PAS de terminer et fermer la réponse au client, avant toute exécution est terminée.
Si vous souhaitez faire un véritable "fire-and-forget" solution, vous avez besoin de plus que cela.
J'ai eu récemment l'exigence que les mails envoyés de manière asynchrone après un formulaire dans une application web a été envoyer.
La seule façon que j'ai trouvée pour résoudre ce problème serait d'utiliser
hangfire
:http://hangfire.io/
OriginalL'auteur Ole Viaud-Murat
Essayez ceci:
OriginalL'auteur Noel