Bonjour, bonsoir à tous
Pour situer le contexte, je dispose d'un projet contenant une référence de services (WCF) dans le but final de faire un petit outil de tests / bench
sur des services ciblés.
Concernant la structure, j'ai décidé de faire une méthode générique qui aura pour but de récupérer un service via son nom de méthode,
ses paramètres puis d'invoker la méthode, le tout de manière asynchrone.
Méthode générique :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
public async Task<T> ExecuteMethod<T>(string nom, object[] param)
{
using var context = new SvDataServiceClient(new InstanceContext(Instance));
Type type = context.GetType();
MethodInfo methode = type.GetMethod(nom);
if (methode != null)
{
var parametres = methode.GetParameters();
if (parametres.Length == 0)
param = null;
}
var result = (Task<T>)methode?.Invoke(context, param);
if (result != null && !result.IsFaulted)
return await result;
return default;
} |
En utilisation simple, la méthode fonctionne bien. J'ai crée une autre classe que j'ai appelé ManagerCore dans laquelle j'appelle ma
méthode générique et fais quelques tests. (Je retourne tous les résultats sous forme de JSON).
Méthode Task d'appel de service :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
public async Task<string[]> GetUserFiltersAsync()
{
var invokeMethod = new MethodInvoker(this);
var benchMark = new BenchMark {
Action = "GetUserFiltersAsync",
Debut = DateTime.Now.Date,
Parametres = new object[] { 2, "SvDataObject.Poco.Article" },
ParametresRequis = invokeMethod.ExtractParams("GetUserFiltersAsync")
};
var BenchTime = new Stopwatch();
BenchTime.Start();
var userFilters = await invokeMethod.ExecuteMethod<UserFilter[]>(benchMark.Action, benchMark.Parametres);
BenchTime.Stop();
var userFiltersJson = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(userFilters, Formatting.Indented));
benchMark.Resultat = new object[] { userFilters.Select(x => x.FilterName) };
benchMark.Duree = BenchTime.ElapsedMilliseconds;
benchMark.Fin = DateTime.Now.Date;
var benchJson = await Task.Factory.StartNew(() => JsonConvert.SerializeObject(benchMark, Formatting.Indented));
return new[] { userFiltersJson, benchJson };
} |
Seulement, je suis actuellement sur une feature qui servira à créer des scénarios, en gros,
faire une succession de tâches asynchrones (appels de services). Pour ça j'ai utilisé Méthode de scénario :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
public async Task<Dictionary<int, string>> Scenario1()
{
var managerCore = new ManagerCore();
var jsonParser = new JsonParser();
var tasks = new List<Task<string[]>>
{
managerCore.GetUserFiltersAsync(),
managerCore.GetCommandeFournisseursAsync(),
managerCore.GetCommandeFournisseurAsync(),
managerCore.GetLignesCommandeFournisseursAsync(),
managerCore.GetOperateursAsync(),
};
await Task.WhenAll(tasks);
foreach (var task in tasks) task.Dispose();
return jsonParser.ParseMultipleJson(new List<string>
{
tasks[0].Result[1],
tasks[1].Result[1],
tasks[2].Result[1],
tasks[3].Result[1],
tasks[4].Result[1],
});
} |
Puis enfin, j'appelle la méthode de mon scénario de cette manière :
1 2 3 4 5 6 7
|
var scenario = await new ExecuteScenario().Scenario1();
foreach (var item in scenario)
{
// Récup des données du dico retourné.
} |
Je rencontre différents problèmes :
Le premier :
Lorsque je démarre mon appli (winform) et que je fais un premier appel, n'importe le quel,
il met un temps interminable à s'exécuter, pourtant la méthode passe bien (log de console) et c'est uniquement sur le premier appel.
Et de manière aléatoire, les appels bloquent indéfiniment, j'ai beau attendre, rien ne se passe (voir ci-dessous) :

Le second (qui survient de manière aléatoire après plusieurs appels async d'un scénario ) :
Mon application plante, principalement au niveau de la méthode générique et me retourne

Log console (Host WCF) :

Le troisième :
Mon application plante aussi au niveau de la méthode générique mais cette fois-ci, l'erreur n'est pas la même
et à vrai dire j'ai aucune idée d'où elle peut venir :

Dernière erreur :
Lorsque je lance en premier un scénario (au lancement du HOST WCF), j'ai l'erreur suivante
System.ServiceModel.FaultException`1*: 'Impossible d'utiliser le contexte lors de la création du modèle.
L'exception peut être levée si le contexte est utilisé dans la méthode OnModelCreating ou si la même instance de contexte
est accessible par plusieurs threads simultanément. Notez qu'il n'est pas garanti que les membres
d'instance de DbContext et les classes associées soient thread-safe.'
A savoir que mon ws est configuré en
ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single]
J'ai l'impression que le/les problème(s) se situe(nt) au niveau du using context et de l'InstanceContext ?? A voir..
Merci d'avoir pris le temps de lire, en espérant avoir quelques pistes.
Merci,
Cordialement.
Partager