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!
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.