Laden...

Wie kann ich ein Einfrieren meiner UI vermeiden?

Erstellt von SKB vor 3 Jahren Letzter Beitrag vor 3 Jahren 812 Views
S
SKB Themenstarter:in
6 Beiträge seit 2020
vor 3 Jahren
Wie kann ich ein Einfrieren meiner UI vermeiden?

Hallo,
ich hätte eine Frage zu einer kleinen Anwendung, die ich aktuell erstelle.

Sie liest die Mails von einem Exchange Server ein, wertet den Body aus und postet dann die Daten an ein PHP Skript auf einem anderen Server. dies geschieht via Timer jede Minute und kann auch manuell per Button ausgelöst werden.

Soweit, so gut.

Wenn nun die Abarbeitung der Mails beginnt, blockiert irgendwie meine UI - ich muss zugeben, mit den Tasks habe ich mich nie groß beschäftigen müssen. Jetzt liegt es wohl auf der Hand.

Kann mir vielleicht jemand etwas unter die Arme greifen, wie ich gleichzeitig die UI bedienbar halte und im Hintergrund die Mails einlese und auch Aktualisierungen an die UI bringe?

Folgender Code friert die UI ein:


        // Button für Manuell
        private void btnManuell_Click(object sender, EventArgs e)
        {
            timer1.Stop();
            FetchNewMail(sender, e);
        }
        public async void FetchNewMail(object sender, EventArgs e)
        {
            if (exchange != null)
            {
                // Display Info, that messages are being fetches
                rBFailure.Text = "Emails werden bearbeitet!";
                FolderId SharedMailbox = new FolderId(WellKnownFolderName.Inbox, g_id);
                SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));

                PropertySet FindItemPropertySet = new PropertySet(BasePropertySet.IdOnly);

                ItemView view = new ItemView(999);
                view.PropertySet = FindItemPropertySet;
                PropertySet GetItemsPropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
                GetItemsPropertySet.RequestedBodyType = BodyType.Text;


                FindItemsResults<Item> emailMessages = null;
                do
                {
                    emailMessages = exchange.FindItems(SharedMailbox, searchFilter, view);
                    if (emailMessages.Items.Count > 0)
                    {
                        int tmp_i = 0;
                        int tmp_message_counter = emailMessages.Items.Count;
                        lblMailCountText.Text = tmp_message_counter.ToString();
                        exchange.LoadPropertiesForItems(emailMessages.Items, GetItemsPropertySet);
                        foreach (Item Item in emailMessages.Items)
                        {
                            tmp_i++;
                            rBFailure.Text = "Bearbeite Nachricht " + tmp_i.ToString() + " von " + tmp_message_counter.ToString();
                            //rBFailure.Text = Item.Body.Text;
                            // Send the Data to the Server and 
                            // Wenn ich dies auskommentiere, läuft das Skript relativ schnell durch
                            if (await postnewDataAsync(Item.Body.Text, "test"))
                            {
                                // Refresh the Numbers
                                worked_mails++;
                                lblMailCountWorkText.Text = worked_mails.ToString();
                                lblMailCountWorkText.Refresh();

                                // Mark the Mail as read
                                //MarkAsReadAndMove(Item.Id);
                            }
                            else
                            {
                                // Refresh the Numbers
                                failed_mails++;
                                lblMailCountFailedText.Text = failed_mails.ToString();
                                lblMailCountFailedText.Refresh();
                            }
                        }
                        rBFailure.Text = "Alle Nachrichten wurden bearbeitet!";
                        rBFailure.Refresh();
                        lblMailCountText.Text = "0";
                        lblMailCountText.Refresh();
                    }
                } while (emailMessages.MoreAvailable);

                if (emailMessages.Items.Count <= 0)
                {
                    rBFailure.Text = "Aktuell keine neuen Nachrichten!";
                    lblMailCountText.Text = "0";
                    lblMailCountText.Refresh();
                }
            }
            // Reset the Timer
            counter = 60;
            StartTimer();
            // Reset the ProgressBar
            pgTimer.Value = 60;
        }
        private async Task<bool> postnewDataAsync(string data, string action)
        {
            var values = new Dictionary<string, string>
            {
                { "action", action },
                { "data", data }
            };

            var content = new FormUrlEncodedContent(values);

            var response = await client.PostAsync("Skript.php", content);

            var responseString = await response.Content.ReadAsStringAsync();
            if (responseString.Contains("Erfolg"))
            {
                return true;
            } else
            {
                return false;
            }
        }


Vielen Dank!

T
2.219 Beiträge seit 2008
vor 3 Jahren

Liegt auch daran, dass die FetchNewMail komplett synchron ausgeführt wird.
Dort läuft deine Schleife synchron, weshalb auch deine UI einfriet.
Lediglich dein Aufruf von postnewDataAsync kann asynchron laufen.
Du solltest dich in Tasks einlesen, wenn du schon asychrone Prozesse nutzen willst.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.

S
SKB Themenstarter:in
6 Beiträge seit 2020
vor 3 Jahren

Danke, ich habe es soweit mit Tasks umgestellt 😉