WPF - mise à Jour de l'Étiquette de Contenu en Cours de Traitement
Eh bien, j'ai essayé plusieurs méthodes d'obtention de ce travail, de fond travailleur, le Répartiteur.Invoquer, le filetage à l'intérieur de la classe appelée, et rien ne semble fonctionner. La meilleure solution à ce jour est une méthode d'Extension qui appelle l'appel de la commande. Aussi j'ai essayé d'éviter de transmettre les données de l'étiquette à travers mes classes d'événements et invoquant simplement dans mon code de traitement, cependant, cela ne faisait aucune différence.
En ce qui concerne l'arrière-plan du composant, j'ai continué de faire des exceptions en disant le fond de travailleur a été occupé, donc j'ai instancié la classe plusieurs fois, cependant, le label visiblement changé une fois l'ensemble de l'opération a été terminée.
J'ai supprimé mon code précédent, voici tout ce qui est pertinent, car il semble que le problème est difficile à résoudre.
Méthode Appelée
private void TestUris()
{
string text = new TextRange(rtxturis.Document.ContentStart, rtxturis.Document.ContentEnd).Text;
string[] lines = Regex.Split(text.Remove(text.Length - 2), "\r\n");
foreach (string uri in lines)
{
SafeUpdateStatusText(uri);
bool result;
string modUri;
if (!uri.Contains("http://"))
{
modUri = uri;
result = StoreData.LinkUriExists(new Uri("http://" + modUri));
}
else
{
modUri = uri.Substring(7);
result = StoreData.LinkUriExists(new Uri(uri));
}
if (!result)
{
Yahoo yahoo = new Yahoo();
yahoo.Status.Sending += (StatusChange);
uint yahooResult = 0;
yahooResult = yahoo.ReturnLinkCount(modUri);
if (yahooResult > 1000 )
{ results.Add(new ScrapeDetails(Guid.NewGuid(), modUri, 1000, "Will be processed", true)); }
else
{ results.Add(new ScrapeDetails(Guid.NewGuid(), modUri, (int)yahooResult, "Insufficient backlinks", false)); }
}
else
{
results.Add(new ScrapeDetails(Guid.NewGuid(), modUri, 0, "Previously been processed", false));
}
}
foreach (var record in results)
{
dgvresults.Items.Add(record);
}
EnableStartButton();
}
Yahoo Classe
public class Yahoo
{
///<summary>
///Returns the amount of links each Uri has.
///</summary>
public uint ReturnLinkCount(string uri)
{
string html;
Status.Update(uri, false); //this is where the status is called
try
{
html = client.DownloadString(string.Format("http://siteexplorer.search.yahoo.com/search?p=http%3A%2F%2F{0}&fr=sfp&bwm=i", uri));
}
catch (WebException ex)
{
ProcessError(ex.ToString());
return 0;
}
return (LinkNumber(html));
}
Statut Classes
public class StatusEventArgs : EventArgs
{
private string _message;
private bool _isidle;
public StatusEventArgs(string message, bool isidle)
{
this._message = message;
this._isidle = isidle;
}
public bool IsIdle
{
get { return _isidle; }
}
public string Message
{
get { return _message; }
}
}
public class Status
{
public Status()
{
}
//Declaring an event, with a custom event arguments class
public event EventHandler<StatusEventArgs> Sending;
//Some method to fire the event.
public void Update(string message, bool isIdle)
{
StatusEventArgs msg = new StatusEventArgs(message, isIdle);
OnUpdate(msg);
}
//The method that invokes the event.
protected virtual void OnUpdate(StatusEventArgs e)
{
EventHandler<StatusEventArgs> handler = Sending;
if (handler != null)
{
handler(this, e);
}
}
}
Méthode Qui modifie les étiquettes de Contenu
private void StatusChange(object sender, StatusEventArgs e)
{
if(!e.IsIdle)
{
lblstatus.Content = e.Message;
lblstatus.Foreground = StatusColors.Green;
lblstatus.Refresh();
}
else
{
lblstatus.Content = e.Message;
lblstatus.Foreground = StatusColors.Grey;
lblstatus.Refresh();
}
}
L'Actualisation de la méthode statique appelée:
public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate() { };
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(DispatcherPriority.Render , EmptyDelegate);
}
Un autre EDIT: Regarder mon code pour un peu plus de temps, je me suis rendu compte, que la boucle foreach va exécuter très rapidement, l'opération qui prend du temps, est
yahooResult = yahoo.ReturnLinkCount(modUri);
Donc j'ai déclaré l'état de la classe (qui gère l'événement et invoque l'étiquette etc) et subscibed à elle. J'ai obtenu de meilleurs résultats, bien qu'il se sent toujours aléatoire, parfois je vois un couple de mises à jour des étiquettes, et parfois, même si l'exact même URI sont passés, aussi bizarre.
- Est-ce une exécution de code à l'intérieur d'un thread différent?
- Non, malheureusement je n'ai toujours pas réussi à le résoudre encore :(.
Vous devez vous connecter pour publier un commentaire.
J'espère qu'il y a qqch. utile...
RÉSOLU OUI WOOHOOOOOOOO 3 jours de tests, d'essais, de tests.
J'ai décidé de commencer un nouveau projet avec l'extension de la méthode ci-dessus et pour la boucle de test de l'INTERFACE utilisateur mise à jour de la fonctionnalité. J'ai commencé à tester les différentes DispatchPrioraties (testé tous).
Bizarrement, j'ai trouvé la plus haute des priorités ont été la pire, par exemple à l'aide d'Envoyer n'ai pas de mise à jour de l'étiquette, Rendu mis à jour deux fois en moyenne. C'était le comportement bizarre j'ai fait l'expérience que j'ai essayé différentes priorités. J'ai découvert de Fond:
La valeur de l'énumération est 4. Les opérations sont traitées après tous les autres non-ralenti les opérations sont terminées.
Maintenant cela sonnait exactement ce que je ne voulais pas, de toute évidence sur l'étiquette mise à jour en cours de traitement, c'est pourquoi je n'ai jamais essayé. Je suppose qu'une fois que l'un de mes méthode a été complété, avant le prochain ça s'appelle, l'INTERFACE utilisateur est mise à jour. Je suis à la rechercher de deviner, mais c'est 100% constamment mises à jour correctement sur les deux opérations distinctes.
Merci à tous.
Bien cela va sembler stupide, mais vous pourriez simplement référence à la formes de l'espace de noms, et puis vous pouvez faire ce
maintenant, le problème à l'aide de ce serait vous utilisez wpf, mais vous pouvez toujours formulaires de référence et l'utilisation de cet espace de noms. L'autre problème est ce n'est jamais dans le québec s'exécuter directement à l'interface utilisateur. Cependant, c'est la plus simple façon de faire les mises à jour des étiquettes que je pouvais penser. Je ne suis pas sûr d'autre raison pour expliquer pourquoi ce serait mauvais pour l'utiliser, mais c'est une solution à l'OP. Si vous avez une bonne raison qu'il est mauvais de ne pas en bas de vote juste de m'informer et d'autres en postant un commentaire. Merci.
serait-il plus facile/mieux pour ajouter les informations sur l'état d'une propriété sur cet objet, et de l'avoir juste le feu de la propriété des notifications de changement?
de cette façon, le texte de l'étiquette (ou autre) pourrait être lié à la propriété plutôt que de devoir l'async travail, essayez de mettre à jour un label?
ou ajouter une méthode de ce genre pour mettre à jour l'état si vous devez mettre à jour?
sinon, je ne pense pas que nous avons assez de détails pour le moment....
J'espère que cela aide:
Utilisation: