Well, I tried several ways to get this to work, the background worker, Dispatcher.Invoke, the threads in the called class, and nothing works. To date, the best solution is an extension method that calls the control. In addition, I tried to avoid passing data for the label through the event classes and simply invoke processing in my code, however this did not matter.
Regarding the background component, I continued to get exceptions, saying that the desktop was busy, so I created the class several times, but the shortcut only changed noticeably after the completion of the whole operation.
I deleted my previous code, here is all that matters, since the problem seems difficult to solve.
Call method
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 class
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)); }
State 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() { }
A Method That Changes Shortcuts Content
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(); } }
Updated static method:
public static class ExtensionMethods { private static Action EmptyDelegate = delegate() { }; public static void Refresh(this UIElement uiElement) { uiElement.Dispatcher.Invoke(DispatcherPriority.Render , EmptyDelegate); }
Another EDITOR: I looked at my code a little longer, I realized that the foreach loop would execute very quickly, an operation that takes time,
yahooResult = yahoo.ReturnLinkCount(modUri);
Therefore, I declared a status class (which processes the event and calls the label, etc.) and is undersecret to it. I got the best results, although it still feels random, sometimes I see a couple of shortcut updates, and sometimes one, even if the same URI is passed, so weird.