Laden...

Forenbeiträge von SKB Ingesamt 6 Beiträge

19.10.2020 - 08:34 Uhr

Du hast eine Liste mit Mails, da weißt du die Anzahl.
Anstatt die zusammen in die Methode zu geben, kannst du sie ja einzeln abarbeiten und den Status aktualisieren.

Funktionieren deine Methoden wirklich?! Du gibst ja nicht mal einen Task zurück. Da macht der Aufruf dann halt auch keinen Sinn.

  
await System.Threading.Tasks.Task.Run(() => PrepareMailsAsync(emailMessages));  
  

Ja, sie funktionieren. Wenn ich die Mails einzeln abarbeite, muss ich ja alle 3000 Mails wieder einzeln an den Server schicken. So habe ich gedacht, das eine komplette Abfrage ok ist.

Kannst Du mir noch beantworten: Wieso muss ich denn einen Task zurückgeben?

Danke 😃

18.10.2020 - 22:34 Uhr

Angepasst habe ich die Tasks nun wie folgt:


private async Task<List<EmailMessage>> CollectMailsAsync()
        {
            FolderId SharedMailbox = new FolderId(WellKnownFolderName.Inbox, g_id);
            SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true));

            PropertySet FindItemPropertySet = new PropertySet(BasePropertySet.IdOnly);

            bool more = true;
            ItemView view = new ItemView(int.MaxValue, 0, OffsetBasePoint.Beginning);
            view.PropertySet = FindItemPropertySet;
            view.OrderBy.Add(EmailMessageSchema.DateTimeReceived, SortDirection.Ascending);
            
            FindItemsResults<Item> findResults;
            List<EmailMessage> emails = new List<EmailMessage>();
            
            while (more)
            {
                findResults = exchange.FindItems(SharedMailbox, searchFilter, view);

                foreach (var item in findResults.Items)
                {
                    emails.Add((EmailMessage)item);
                    
                }
                more = findResults.MoreAvailable;
                if (more)
                {
                    view.Offset += 1000;
                }
            }
            return emails;
        }

        private async Task<List<EmailMessage>> PrepareMailsAsync(List<EmailMessage> emails)
        {
            PropertySet GetItemsPropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
            GetItemsPropertySet.RequestedBodyType = BodyType.Text;
            GetItemsPropertySet.BlockExternalImages = true;
            exchange.TraceEnabled = false;
            exchange.LoadPropertiesForItems(emails, GetItemsPropertySet);
            return emails;
        }


                    List<EmailMessage> emailMessages = null;
                    emailMessages = await System.Threading.Tasks.Task.Run(() => CollectMailsAsync());

                    // String for High Mail Load
                    string mail_message = emailMessages.Count() + " Emails wurden vom Server eingelesen ";

                    if (emailMessages.Count() > 1000)
                    {
                        mail_message += "und werden nun aufbereitet.\nDies kann einen Moment dauern ...";
                    } else
                    {
                        mail_message += "und werden nun aufbereitet ...";
                    }
                    lblStatus.Text = mail_message;
                    lblStatus.Refresh();
                    emailMessages = await System.Threading.Tasks.Task.Run(() => PrepareMailsAsync(emailMessages));

Meine GUI blockiert nicht und alle Mails werden sauber abgearbeitet. Jedoch fehlt mir noch die Idee, wie ich dort einen Status einbauen kann.

18.10.2020 - 21:17 Uhr

Hallo Virus,
ich habe das await davor stehen, weil ich sonst einen Compiler Fehler erhalte.

Hast du einen Tipp, wie man dies besser abarbeiten könnte?

18.10.2020 - 11:00 Uhr

Hallo,
ich lade per EWS einen ganzen Schwung an Mails (>3000) und lasse diese dann in einer e-Mail Liste ablegen, damit ich alle Mails nacheinander bearbeiten kann. Soweit so gut.

Da ich ja dann zu jeder Mail die Eigenschaften brauche, lade ich mit


exchange.LoadPropertiesForItems(emails, GetItemsPropertySet);

die Details vom Server. Leider dauert dies bei dem Haufen an Mails immer eine Weile. Hier würde ich gerne eine Statusmeldung einrichten, die zeigt, wie weit der Abruf schon ist. Ist sowas möglich?

Abholen der Mails sieht so aus:


private List<EmailMessage> CollectMailsAsync()
        {
            FolderId SharedMailbox = new FolderId(WellKnownFolderName.Inbox, g_id);
            SearchFilter searchFilter = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true));

            PropertySet FindItemPropertySet = new PropertySet(BasePropertySet.IdOnly);

            bool more = true;
            ItemView view = new ItemView(int.MaxValue, 0, OffsetBasePoint.Beginning);
            view.PropertySet = FindItemPropertySet;
            view.OrderBy.Add(EmailMessageSchema.DateTimeReceived, SortDirection.Ascending);
            
            FindItemsResults<Item> findResults;
            List<EmailMessage> emails = new List<EmailMessage>();
            
            while (more)
            {
                findResults = exchange.FindItems(SharedMailbox, searchFilter, view);

                foreach (var item in findResults.Items)
                {
                    emails.Add((EmailMessage)item);
                    
                }
                more = findResults.MoreAvailable;
                if (more)
                {
                    view.Offset += 1000;
                }
            }
            return emails;
        }

Funktion, um die Eigenschaften der Mails abzuholen:


        private async Task<List<EmailMessage>> PrepareMailsAsync(List<EmailMessage> emails)
        {
            PropertySet GetItemsPropertySet = new PropertySet(BasePropertySet.FirstClassProperties);
            GetItemsPropertySet.RequestedBodyType = BodyType.Text;
            GetItemsPropertySet.BlockExternalImages = true;
            exchange.TraceEnabled = false;
            exchange.LoadPropertiesForItems(emails, GetItemsPropertySet);
            return emails;
        }

Funktion, um die Mails zu bearbeiten:


        public async void FetchNewMail(object sender, EventArgs e)
        {
            if (exchange != null)
            {
                try
                {
                    List<EmailMessage> emailMessages = null;
                    emailMessages = await System.Threading.Tasks.Task.Run(() => CollectMailsAsync());
                    emailMessages = await System.Threading.Tasks.Task.Run(() => PrepareMailsAsync(emailMessages));
                }
            }
        }

Vielen Dank für Eure Zeit!

18.10.2020 - 10:49 Uhr

Danke, ich habe es soweit mit Tasks umgestellt 😉

15.10.2020 - 20:15 Uhr

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!