Beh, ho provato diversi metodi per far funzionare tutto questo, l'operatore in background, Dispatcher.Invoke, il threading all'interno della classe chiamata e nulla sembra funzionare. La soluzione migliore finora è un metodo di estensione che chiama il richiamo del controllo. Inoltre, ho cercato di evitare di passare i dati per l'etichetta attraverso le mie classi di eventi e semplicemente invocando il mio codice di elaborazione, tuttavia ciò non ha fatto alcuna differenza.WPF - Aggiornamento del contenuto dell'etichetta durante l'elaborazione
Riguardo al componente di sfondo, ho continuato a ottenere eccezioni dicendo che lo sfondo era occupato, quindi ho istanziato la classe diverse volte, tuttavia l'etichetta cambiava solo visibilmente una volta completata l'intera operazione.
Ho rimosso il mio codice precedente, ecco tutto ciò che è rilevante, in quanto sembra che il problema sia difficile da risolvere.
Metodo essere chiamato
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));
}
Classi di stato
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);
}
}
}
metodo che modifica le etichette Contenuto
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();
}
}
Il metodo statico Refresh chiamato:
public static class ExtensionMethods
{
private static Action EmptyDelegate = delegate() { };
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(DispatcherPriority.Render , EmptyDelegate);
}
Un altro EDIT: Fissando il mio codice per un po 'di più, mi sono reso conto, che il foreach loop verrà eseguito molto rapidamente, l'operazione che richiede tempo, è
yahooResult = yahoo.ReturnLinkCount(modUri);
Pertanto ho dichiarato edita la classe di stato (che gestisce l'evento e invoca l'etichetta, ecc.) e vi si iscrive. Ho ottenuto risultati migliori, anche se mi sembrano ancora casuali, a volte vedo un paio di aggiornamenti delle etichette e, a volte, anche se viene passato lo stesso identico URI, così strano.
È questo il codice in esecuzione all'interno di un thread diverso? – decyclone
No, purtroppo non sono ancora riuscito a risolverlo ancora :(. – Ash