2017-10-13 7 views
0

Voilà comment fonctionne mon système:écran Rafraîchissant sur une mauvaise voie conduit à la performance des applications émet

2 ordinateurs utilisent différentes applications, mais même base de données (tableau: commandes).

Le 1er ordinateur effectue des ordres et les écrit dans la base de données. Le 2ème ordinateur doit afficher les nouvelles commandes toutes les 5 secondes.

Je vais bientôt décrire (pour éviter de texte) ce que je dois faire et comment je l'ai fait en ce moment:

  • 2ème application ordinateurs ont besoin « d'aller à la base de données » toutes les 5 secondes pour vérifier les nouveaux commandes et les montrer à l'écran

Et quand il y a beaucoup de commandes et quand je le fais assez souvent mon application est en panne.

Voici comment mon application fonctionne en ce moment:

public MainWindow() 
{ 

    try 
    { 
     InitializeComponent(); 
     this.WindowStartupLocation = WindowStartupLocation.CenterScreen; 
     this.WindowState = WindowState.Maximized; 
     //When app runs for first time get all orders 
     var ordersList = OrdersController.GetOrders(); 


     collectionViewSource.Source = ordersList; 
     collectionViewSource.GroupDescriptions.Add(new PropertyGroupDescription("NumberOfOrder")); 
     DataContext = collectionViewSource; 

     //Here I'm refreshing screen every 5 seconds 




DispatcherTimer timer = new DispatcherTimer(); 
     timer.Interval = TimeSpan.FromSeconds(5)); 
     timer.Tick += timer_Tick; 
     timer.Start(); 

    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 

} 

void timer_Tick(object sender, EventArgs e) 
{ 
    //Every 5 seconds get all orders from database 
    var ordersList = OrdersController.GetOrders(); 
    collectionViewSource.Source = null; 

    collectionViewSource.Source = ordersList; 
    DataContext = collectionViewSource; 
} 

méthode GetOrders:

public static List<Orders> GetOrders() 
{ 
      DataServices.DB.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, DataServices.DB.Orders); 

      var results = DataServices.DB.proc_Orders_GetAll().ToList(); 

      List<Orders> localOrders = new List<Orders>(); 

      foreach (var item in results) 
      { 
       Orders local = new Orders(); 
       local.Sender = item.Sender; 
       local.Quantity = Convert.ToDecimal(item.Quantity); 
       local.ArticleTitle = item.ArticleTitle; 
       local.DateOfOrder = Convert.ToDateTime(item.DateOfOrder); 
       lokalnen.Add(local); 
      } 
      return localOrders; 
} 

Mais ce code ci-dessus est pas si bon, cela cause écrasait ma demande s'il y a un ordre de lot .. Probablement parce que l'interface utilisateur restitue tout le temps encore et encore

Déplacer ce "travail de rafraîchissement" vers une autre tâche peut résoudre le problème. ue, donc j'ai essayé quelque chose comme ceci:

Tout d'abord créer une nouvelle méthode RefreshScreen qui pourrait ressembler à ceci:

private void RefreshScreen() 
{ 
    var ordersList = OrdersController.GetOrders(); 
    collectionViewSource.Source = null; 

    collectionViewSource.Source = ordersList; 
    DataContext = collectionViewSource; 
} 

Et je me suis déplacé ce RefreshScreen() à une nouvelle tâche comme celui-ci:

void timer_Tick(object sender, EventArgs e) 
{ 
    //Instead old code where I set source of my list and of my datagrid directlly in timer tick now I moved it to new method and calling that method from a new task 
    Task.Factory.StartNew(() => RefreshScreen()) 
     .ContinueWith(task => 
    { 

    }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 

} 

Mais cela fait de nouveau mon béguin d'application après un moment ... Je ne sais vraiment pas comment résoudre ça, peut-être quelque chose avec des collections Observablle ou autre, Je ne sais pas ...

Toute sorte d'aide serait génial et génial pour empêcher mon application d'écraser! Merci!

Edit: après l'exécution de l'application de mon studio visuel je reçois ceci après quelques secondes (avec une solution qui est compris tâche timer tick):

enter image description here

enter image description here

+0

@mjwills il ya simplement un message contextuel avec une erreur après un certain temps et après que je clique sur ok, l'application s'arrête. Et je me suis rendu compte que cela se produisait si je cliquais quelque part sur l'interface utilisateur alors que le rafraîchissement était en cours. –

+0

@mjwills Je vais essayer de faire en sorte que cette erreur se produise, donc je pourrais vous montrer, mais ça ne s'affiche pas tout le temps, mais je savoir ce qui se passe tout le temps: l'application est très lente, à cause de souvent l'interface de resfreshing/rendu je suppose ... –

+0

Comment l'application plante-t-elle? Est-ce que ça se bloque ou obtenez-vous une exception? Que dit le message d'exception? – mm8

Répondre

-2

Essayez la mise en œuvre SignalR. Fonctionne plutôt bien pour ce type d'opérations

0

Vous devez interroger la base de données sur un thread d'arrière-plan, mais vous ne pouvez pas accéder à la propriété DataContext ou à toute autre propriété d'un élément d'interface utilisateur à partir d'un thread d'arrière-plan. C'est pourquoi vous obtenez l'exception "Le thread appelant ne peut pas accéder ..".

Vous pouvez essayer de démarrer une Task qui appelle la méthode GetOrders() sur un fil de fond:

void timer_Tick(object sender, EventArgs e) 
{ 
    Task.Factory.StartNew(() => 
    { 
     return OrdersController.GetOrders() 
    }).ContinueWith(task => 
    { 
     collectionViewSource.Source = task.Result; 
     DataContext = collectionViewSource; 
    }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
} 

Mais si elle est le code qui fonctionne dans le délégué ContinueWith une fois que la requête a terminé qui est lent, vous n'ont pas d'autre choix que d'aller chercher moins d'enregistrements.

Vous devez également vous assurer que vous n'avez pas désactivé la virtualisation de l'interface utilisateur. Vous pouvez également essayer sans grouper les résultats. Cela peut être lent aussi.

+0

orderList n'est pas reconnu là-bas, il devrait être déclaré comme une liste globale? –

+0

Désolé, la propriété Source doit être définie sur le résultat de la tâche. J'ai édité la réponse. – mm8

+0

Ce code semble fonctionner, mais de toute façon, je me demande est-il possible de \t \t \t \t \t plus à améliorer cette application plus rapide, ce que je veux dire ici: quand je défilement vers le bas et l'application est tout rafraîchi ralentit, et le défilement est soudainement en retard. Je ne suis pas loin de changer tout le concept si je pouvais le rendre plus fonctionnel. –