Bonsoir,
je demande votre aide ce soir car je suis face à un problème de mémoire incompréhensible.
Je possédais mon propre dispatcher au par avant mais il consommait beaucoup trop donc j'ai opté pour le Dispatcher de BiM bien plus optimisé.
Je l'ai un peu modifié, le voici:
ClientDispatcher.cs
Cliquez pour révéler
Cliquez pour masquer
public class ClientDispatcher
{
private SortedDictionary<MessagePriority, Queue<Tuple<NetworkMessage, object>>> messagesToDispatch = new SortedDictionary<MessagePriority, Queue<Tuple<NetworkMessage, object>>>();
private int currentThreadId;
private object currentProcessor;
public object CurrentProcessor
{
get { return currentProcessor; }
}
public int CurrentThreadId
{
get { return currentThreadId; }
}
private ManualResetEventSlim resumeEvent = new ManualResetEventSlim(true);
private ManualResetEventSlim messageEnqueuedEvent = new ManualResetEventSlim(false);
private bool stopped;
private bool dispatching;
public event Action<ClientDispatcher, NetworkMessage> MessageDispatched;
protected void OnMessageDispatched(NetworkMessage message)
{
var evnt = MessageDispatched;
if (evnt != null)
MessageDispatched(this, message);
}
public ClientDispatcher()
{
foreach (var value in Enum.GetValues(typeof(MessagePriority)))
{
messagesToDispatch.Add((MessagePriority)value, new Queue<Tuple<NetworkMessage, object>>());
}
}
public bool Stopped
{
get { return stopped; }
}
public void Enqueue(NetworkMessage message, bool executeIfCan = true)
{
Enqueue(message, null, executeIfCan);
}
public virtual void Enqueue(NetworkMessage message, object token, bool executeIfCan = true)
{
if (executeIfCan && IsInDispatchingContext())
{
Dispatch(message, token);
}
else
{
lock (messageEnqueuedEvent)
{
messagesToDispatch[MessagePriority.Normal].Enqueue(Tuple.Create(message, token));
if (!dispatching)
messageEnqueuedEvent.Set();
}
}
}
public bool IsInDispatchingContext()
{
return Thread.CurrentThread.ManagedThreadId == currentThreadId &&
currentProcessor != null;
}
public void ProcessDispatching(object processor)
{
if (stopped)
return;
if (Interlocked.CompareExchange(ref currentThreadId, Thread.CurrentThread.ManagedThreadId, 0) == 0)
{
currentProcessor = processor;
dispatching = true;
var copy = messagesToDispatch.ToArray();
foreach (var keyPair in copy)
{
if (stopped)
break;
while (keyPair.Value.Count != 0)
{
if (stopped)
break;
var message = keyPair.Value.Dequeue();
if (message != null)
Dispatch(message.Item1, message.Item2);
}
}
currentProcessor = null;
dispatching = false;
Interlocked.Exchange(ref currentThreadId, 0);
}
lock (messagesToDispatch)
{
if (messagesToDispatch.Sum(x => x.Value.Count) > 0)
messageEnqueuedEvent.Set();
else
messageEnqueuedEvent.Reset();
}
}
protected virtual void Dispatch(NetworkMessage message, object token)
{
MethodInfo method = FrameManager.GetMethodByName(message.ToString());
if (method == null)
return;
if (method != null)
{
object[] parameters = new object[] { token, message };
method.Invoke(null, parameters);
}
OnMessageDispatched(message);
}
/// <summary>
/// Block the current thread until a message is enqueued
/// </summary>
public void Wait()
{
if (stopped)
resumeEvent.Wait();
if (messagesToDispatch.Sum(x => x.Value.Count) > 0)
return;
messageEnqueuedEvent.Wait();
}
public void Resume()
{
if (!stopped)
return;
stopped = false;
resumeEvent.Set();
}
public void Stop()
{
if (stopped)
return;
stopped = true;
resumeEvent.Reset();
}
public void Dispose()
{
Stop();
foreach (var messages in messagesToDispatch)
{
messages.Value.Clear();
}
}
private Stopwatch _spy;
/// <summary>
/// Says how many milliseconds elapsed since last message.
/// </summary>
public long DelayFromLastMessage
{
get
{
if (_spy == null) _spy = Stopwatch.StartNew(); return _spy.ElapsedMilliseconds;
}
}
/// <summary>
/// Reset timer for last received message
/// </summary>
protected void ActivityUpdate()
{
if (_spy == null)
_spy = Stopwatch.StartNew();
else
_spy.Restart();
}
}
public enum MessagePriority
{
VeryHigh = 4,
High = 3,
Normal = 2,
Low = 1,
VeryLow = 0,
}
La classe qui gère le ClientDispatcher:
DispatcherTask.cs
Cliquez pour révéler
Cliquez pour masquer
public class DispatcherTask
{
public ClientDispatcher Dispatcher { get; private set; }
public bool Running
{
get;
private set;
}
public object Processor { get; set; }
public DispatcherTask(ClientDispatcher dispatcher)
{
Dispatcher = dispatcher;
Processor = this;
}
public DispatcherTask(ClientDispatcher dispatcher, object processor)
{
Dispatcher = dispatcher;
Processor = processor;
}
public void Start()
{
Running = true;
Task.Factory.StartNew(Process);
}
public void Stop()
{
Running = false;
}
private void Process()
{
while (Running)
{
Dispatcher.Wait();
if (Running)
Dispatcher.ProcessDispatching(Processor);
}
}
}
Et actuellement au lancement mon Bot consomme 0% sur le processeur, 100 000K de mémoire et 16 Threads.
Puis a la connexion tout reste stable mais la mémoire monte lentement.
Au bout de 5 minutes la mémoire continue a grimper et mon bot passe à 40% / 50% d'utilisation du processeur.
Je l'ai laissé tourner une heure pour voir, je suis arrivé à 800 000K pour un seul compte, 40/50 Threads, mon ventilo geulait et je pouvait même plus bouger les fenêtres enfants tellement sa bugait.
Je me déconnecte et rien ne change, incompréhensible, cela s'empire si on multiplie le nombres de comptes.
Je ne m'en rendait pas compte puisque mes tests a chaque connexion ne durent pas plus de 5mins donc je ne ressentais aucun lag sur les fenêtres.
J'ai essayé de supprimer l'interface et ma minimap mais cela n'a rien changé. Sa commence a buger au moment ou on connecte un compte.
Je doute que cela vienne du Dispatcher puisque il est stoppé a la déconnexion, mais c'est la seul chose qui tourne sur le bot pendant ces montées de mémoires.
Si quelqu'un pouvait m'aider :ugeek:
Bonne soirée