J'ai une application MVC dans laquelle les méthodes d'action doivent être exécutées dans un certain ordre. Récemment, j'ai eu quelques problèmes étranges et j'ai supposer que c'est dû au fait que j'ai ne pas faire de synchronisation des threads . J'ai à peine travaillé avec le multithreading et je ne connais pas grand-chose à ce sujet. J'ai essayé d'implémenter une sorte de verrouillage où je dois verrouiller selon Id. J'ai donc implémenté la classe ci-dessous pour obtenir les objets de verrouillage requis.
public class ReportLockProvider
: IReportLockProvider
{
readonly ConcurrentDictionary<long, object> lockDictionary
= new ConcurrentDictionary<long, object>();
public object ProvideLockObject(long reportId)
{
return lockDictionary.GetOrAdd(reportId, new object());
}
}
J'ai essayé de l'utiliser comme suit :
ReportLockProvider lockProvider = new ReportLockProvider();
public async ActionResult MyAction(long reportId)
{
lock(lockProvider.ProvideLockObject(reportId))
{
// Some operations
await Something();
// Some operation
}
}
J'espérais que cela fonctionnerait, mais cela n'a pas été le cas, car j'ai utilisé await
à l'intérieur lock
corps. J'ai cherché un peu et je suis tombé sur SemaphoreSlim
en cette réponse . Le problème est que je dois obtenir l'objet de verrouillage selon Id . Comment faire ? Est-il possible de créer plusieurs SemaphoreSlim
objets ? Puis-je modifier le code comme suit :
public class ReportLockProvider
: IReportLockProvider
{
readonly ConcurrentDictionary<long, SemaphoreSlim> lockDictionary
= new ConcurrentDictionary<long, SemaphoreSlim>();
public SemaphoreSlim ProvideLockObject(long reportId)
{
return lockDictionary.GetOrAdd(reportId, new SemaphoreSlim(1, 1));
}
}
public async ActionResult MyAction(long reportId)
{
var lockObject = ReportLockProvider.ProvideLockObject(reportId);
await lockObject.WaitAsync();
try
{
// Some operations
await Something();
// Some operation
}
finally
{
lockObject.Release();
}
}
L'autre question est la suivante : puis-je utiliser SemaphoreSlim
en non synchrone méthodes ? Existe-t-il une meilleure option ?