myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Office-Technologien » Wie kann ich beim Abrufen von Exchange-Properties einen Status oder Ladebalken anzeigen?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Wie kann ich beim Abrufen von Exchange-Properties einen Status oder Ladebalken anzeigen?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
SKB SKB ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.10.2020
Beiträge: 6


SKB ist offline

Wie kann ich beim Abrufen von Exchange-Properties einen Status oder Ladebalken anzeigen?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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

C#-Code:
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:

C#-Code:
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:

C#-Code:
        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:

C#-Code:
        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 11:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.657
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@SKB
Wozu machst du ein await und gleichzeitig Task.Run(), wenn deine Methode doch *Async heißen?
Eigentlich sollten diese einen Task zurückgeben, den du dann per await abarbeiten lässt.
So hast du Methoden, die synchron arbeiten, Async heißen und damit eigentlich andeuten, dass diese asynchron laufen.
Ebenfalls sollten Async Methoden, die Tasks liefern auch async markiert sein.

Da du die Menge an Emails anfangs nicht kennen kannst, wirst du erst eine generische Ladeanzeige anzeigen müssen z.B. mit der Informations, dass die Emails ermittelt werden.
Erst wenn du alle Emails hast, kennst du die Anzahl davon.
Jetzt würde ich jeweils gestaffelt für X Emails die Eigenschaften nachladen.
Damit kannst du dann auch eine entsprechende Anzeige umsetzen.

Müsste dann aber asynchron laufen, damit die UI nicht wieder blockiert.

T-Virus
18.10.2020 11:13 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
SKB SKB ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.10.2020
Beiträge: 6

Themenstarter Thema begonnen von SKB

SKB ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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 21:17 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Papst Papst ist männlich
myCSharp.de-Mitglied

Dabei seit: 28.09.2014
Beiträge: 321
Entwicklungsumgebung: VS2017
Herkunft: Kassel


Papst ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Wie lautet denn dein Compiler Fehler?

Deine Methode "PrepareMailsAsync" heißt zwar Async und ist als Async markiert, ist aber nicht async und gibt vor allem keinen Task zurück. Sollte also in jedem Fall einen Compiler Fehler geben, weil der Rückgabetyp nicht stimmt.
18.10.2020 22:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
SKB SKB ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.10.2020
Beiträge: 6

Themenstarter Thema begonnen von SKB

SKB ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Angepasst habe ich die Tasks nun wie folgt:

C#-Code:
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;
        }

C#-Code:
                    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 22:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 157
Entwicklungsumgebung: Visual Studio 6.0 Enterprise


JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

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.

C#-Code:
await System.Threading.Tasks.Task.Run(() => PrepareMailsAsync(emailMessages));

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von JimStark am 19.10.2020 07:44.

19.10.2020 07:43 Beiträge des Benutzers | zu Buddylist hinzufügen
SKB SKB ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.10.2020
Beiträge: 6

Themenstarter Thema begonnen von SKB

SKB ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von JimStark:
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.

C#-Code:
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 :-)
19.10.2020 08:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.657
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@SKB
Weil Async Methoden immer einen Task/Value Task zurückgeben müssen.
Sonst deuten diese eine asynchrone Verarbeitung an, die sich nicht leisten.
Ist aber Teil der Programmierung mit Tasks über async/await.
Solltest du dir ggf. nochmal anschauen, wie es richtig gemacht wird.
Spätestens jetzt wo du in der UI arbeitest, solltest du die Tasks auch richtig anwenden.

Nachtrag:
Ich hatte oben auch schon den Hinweis gegeben, dass du deine Emails gestaffelt an den Server senden sollst.
Dadurch sparst du dir viele Roundtrips zwischen dir und dem Server und der Server muss nicht jede Email einzeln abfragen bzw. deren Eigenschaften.
Teste hier am besten aus, ab welcher Menge die Dauer zum abfragen der Eigenschaften noch kurz genug ist und dann hast du schon einen guten Ansatz.

T-Virus

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von T-Virus am 19.10.2020 08:44.

19.10.2020 08:42 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als ein Monat.
Der letzte Beitrag ist älter als ein Monat.
Antwort erstellen


© Copyright 2003-2020 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 03.12.2020 01:55