后台工作阻塞UI

本文关键字:UI 工作 后台 | 更新日期: 2023-09-27 18:02:27

在使用Thread.Sleep()方法之前,我的UI仍然通过使用后台工作者阻塞。但是超过5万步,我的程序就会非常慢。

下面是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()。但是唯一的方法是thread . sleep ();

后台工作阻塞UI

你的UI冻结的最有可能的原因是你正在做一些接触到主UI线程的事情,并在那里执行了相当多的工作。

这一行最有可能是罪魁祸首,如果它被调用得非常快,或者如果Progress_Changed事件做了很多工作……该方法中的所有内容都在主线程中执行。

worker.ReportProgress(1, new_emoticons.Count());                            

如果你不需要它,就注释掉上面的行,或者确保它很少被调用:

if ((counter % 10) == 0)
    worker.ReportProgress(1, new_emoticons.Count());

避免Thread.Sleep,除非你知道你需要它,并且肯定避免Application.DoEvents()