后台工作人员已阻止 UI
Backgroundworker blocked UI
在我使用 Thread.Sleep() 方法之前,我的 UI 仍在使用后台程序进行阻塞。但是超过 50.000 步,我的程序会非常慢。
这里是 do_work 方法:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
List<object> arguments = e.Argument as List<object>;
SortedDictionary<string, List<string>> installed_emoticons, twitch_emoticons, new_emoticons;
int counter = 0;
sw.Restart();
installed_emoticons = arguments[1] as SortedDictionary<string, List<string>>;
switch (Convert.ToInt32(arguments[0]))
{
//umwandeln dynamic twitch_emoticons in SortedDictionarray
//prüfen welche Emoticons neu heruntergeladen werden müssen
case 1:
twitch_emoticons = new SortedDictionary<string, List<string>>();
new_emoticons = new SortedDictionary<string, List<string>>();
dynamic din_twitch_emoticons = (arguments[2] as dynamic)["emoticons"];
foreach (dynamic new_emoticon in din_twitch_emoticons)
{
//Prüfen ob der worker abgebrochen werden soll
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
//Zerlegen der informationen aus der dynamischen Variable
string code = new_emoticon["code"].ToString();
string id = new_emoticon["id"].ToString();
string emoticon_set = new_emoticon["emoticon_set"].ToString();
//Prüfen ob das Emoticonset einen Wert enthält
if (emoticon_set == null) emoticon_set = "0";
//Prüfen ob ein Standard Emoticon enthalten ist
if (standard_emotes.ContainsKey(code)) code = standard_emotes[code];
//Speichern der Emoticons aus der dynmaischen Twitch Variablen in ein SortedDicitionary
if (!twitch_emoticons.ContainsKey(code))
twitch_emoticons.Add(code, new List<string> { @"\images\emoticons\" + emoticon_set + "\" + id + ".png" });
else
twitch_emoticons[code].Add(@"\images\emoticons\" + emoticon_set + "\" + id + ".png");
//Prüfen ob ein neues Emoticon enthalten ist
if (!installed_emoticons.ContainsKey(code))
{
if (!new_emoticons.ContainsKey(code))
new_emoticons.Add(code, new List<string> { @"\images\emoticons\" + emoticon_set + "\" + id + ".png" });
else if (!new_emoticons[code].Contains(@"\images\emoticons\" + emoticon_set + "\" + id + ".png"))
new_emoticons[code].Add(@"\images\emoticons\" + emoticon_set + "\" + id + ".png");
}
else if (!installed_emoticons[code].Contains(@"\images\emoticons\" + emoticon_set + "\" + id + ".png"))
{
if (!new_emoticons.ContainsKey(code))
new_emoticons.Add(code, new List<string> { @"\images\emoticons\" + emoticon_set + "\" + id + ".png" });
else
new_emoticons[code].Add(@"\images\emoticons\" + emoticon_set + "\" + id + ".png");
}
counter++;
if ((counter % 4) == 0)
System.Threading.Thread.Sleep(1);
worker.ReportProgress(1, new_emoticons.Count());
}
//e.Result = null;
e.Result = new List<object> {2, installed_emoticons, twitch_emoticons, new_emoticons };
break;
//
case 2:
break;
}
}
我用 Application.DoEvents() 试试。但唯一的方法是 Thred.Sleep();
您的 UI 冻结的最可能原因是您正在做的事情会延伸到主 UI 线程并在那里执行大量工作。
这一行最有可能是罪魁祸首,如果它被非常快速地调用或者如果 Progress_Changed
事件正在做很多工作......该方法中的所有内容都在主线程上执行。
worker.ReportProgress(1, new_emoticons.Count());
如果不需要上面的行,请将其注释掉,或者确保不经常调用它:
if ((counter % 10) == 0)
worker.ReportProgress(1, new_emoticons.Count());
避免Thread.Sleep
除非你知道你需要它,并且绝对避免Application.DoEvents()
.
在我使用 Thread.Sleep() 方法之前,我的 UI 仍在使用后台程序进行阻塞。但是超过 50.000 步,我的程序会非常慢。
这里是 do_work 方法:
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
List<object> arguments = e.Argument as List<object>;
SortedDictionary<string, List<string>> installed_emoticons, twitch_emoticons, new_emoticons;
int counter = 0;
sw.Restart();
installed_emoticons = arguments[1] as SortedDictionary<string, List<string>>;
switch (Convert.ToInt32(arguments[0]))
{
//umwandeln dynamic twitch_emoticons in SortedDictionarray
//prüfen welche Emoticons neu heruntergeladen werden müssen
case 1:
twitch_emoticons = new SortedDictionary<string, List<string>>();
new_emoticons = new SortedDictionary<string, List<string>>();
dynamic din_twitch_emoticons = (arguments[2] as dynamic)["emoticons"];
foreach (dynamic new_emoticon in din_twitch_emoticons)
{
//Prüfen ob der worker abgebrochen werden soll
if (worker.CancellationPending)
{
e.Cancel = true;
return;
}
//Zerlegen der informationen aus der dynamischen Variable
string code = new_emoticon["code"].ToString();
string id = new_emoticon["id"].ToString();
string emoticon_set = new_emoticon["emoticon_set"].ToString();
//Prüfen ob das Emoticonset einen Wert enthält
if (emoticon_set == null) emoticon_set = "0";
//Prüfen ob ein Standard Emoticon enthalten ist
if (standard_emotes.ContainsKey(code)) code = standard_emotes[code];
//Speichern der Emoticons aus der dynmaischen Twitch Variablen in ein SortedDicitionary
if (!twitch_emoticons.ContainsKey(code))
twitch_emoticons.Add(code, new List<string> { @"\images\emoticons\" + emoticon_set + "\" + id + ".png" });
else
twitch_emoticons[code].Add(@"\images\emoticons\" + emoticon_set + "\" + id + ".png");
//Prüfen ob ein neues Emoticon enthalten ist
if (!installed_emoticons.ContainsKey(code))
{
if (!new_emoticons.ContainsKey(code))
new_emoticons.Add(code, new List<string> { @"\images\emoticons\" + emoticon_set + "\" + id + ".png" });
else if (!new_emoticons[code].Contains(@"\images\emoticons\" + emoticon_set + "\" + id + ".png"))
new_emoticons[code].Add(@"\images\emoticons\" + emoticon_set + "\" + id + ".png");
}
else if (!installed_emoticons[code].Contains(@"\images\emoticons\" + emoticon_set + "\" + id + ".png"))
{
if (!new_emoticons.ContainsKey(code))
new_emoticons.Add(code, new List<string> { @"\images\emoticons\" + emoticon_set + "\" + id + ".png" });
else
new_emoticons[code].Add(@"\images\emoticons\" + emoticon_set + "\" + id + ".png");
}
counter++;
if ((counter % 4) == 0)
System.Threading.Thread.Sleep(1);
worker.ReportProgress(1, new_emoticons.Count());
}
//e.Result = null;
e.Result = new List<object> {2, installed_emoticons, twitch_emoticons, new_emoticons };
break;
//
case 2:
break;
}
}
我用 Application.DoEvents() 试试。但唯一的方法是 Thred.Sleep();
您的 UI 冻结的最可能原因是您正在做的事情会延伸到主 UI 线程并在那里执行大量工作。
这一行最有可能是罪魁祸首,如果它被非常快速地调用或者如果 Progress_Changed
事件正在做很多工作......该方法中的所有内容都在主线程上执行。
worker.ReportProgress(1, new_emoticons.Count());
如果不需要上面的行,请将其注释掉,或者确保不经常调用它:
if ((counter % 10) == 0)
worker.ReportProgress(1, new_emoticons.Count());
避免Thread.Sleep
除非你知道你需要它,并且绝对避免Application.DoEvents()
.