Witam,
Staram się napisać program tak aby korzystał on w dużym stopniu z wielowątkowości (mnóstwo operacji w których trzeba czekać na efekt pobrany z sieci), przy okazji traktuję to jako ćwiczenie. Mam zatem pytanie tego typu:
- Obiekt klasy Log został utworzony w wątku głównym (w tym samym co GUI WinFroms)
- Przekazuję go do obiektu który ma go użyć (aplikacja ma kilka róznych logów)
3.Dodatkowo Log posiada zdarzenie które jest wywoływane w momencie aktualizacji jego zawartości.
Log EmailLog = new LogUtils.Log();
EmailLog.LogChanged += Form1_LogChanged;
Email.EmailListener.InitEmailListener(EmailLog, "fdsf", 0, false, "sdf", "asd");
Metoda Form1_LogChanged utworzona w wątku głównym UI bezpośrednio aktualizuje UI w wypadku zmiany jego zawartości.
4. Wywołuję metodę statyczną InitEmailListener:
Ogólnie odpowiada ona za inicjalizację obiektu który jest singletonem i wykonuje sprawdzenie możliwości zalogowania za pomocą AttemptLogin
public static void InitEmailListener(LogUtils.Log Log, string hostname, int port, bool useSsl, string username, string password)
{
ThreadedListener = new EmailListener();
ThreadedListener.Log = Log;
ThreadedListener.HostName = hostname;
ThreadedListener.Port = port;
ThreadedListener.UseSss = useSsl;
ThreadedListener.UserName = username;
ThreadedListener.Password = password;
try
{
ThreadedListener.AttemptLogin();
}
catch
{
ThreadedListener.Log.AddMessage("Failed to initialize EmailListener",true);
ThreadedListener = null;
return;
}
}
- Wywoływane jest AttemptLogin:
private async void AttemptLogin()
{
Log.AddMultilineMessage(string.Format("Attempt to login to:{0}",UserName),true);
Log.AddMultilineMessage(string.Format("Hostname:{0}", HostName), false);
Log.AddMultilineMessage(string.Format("Port:{0}", Port), false);
Log.AddMultilineMessage(string.Format("UserName:{0}", UserName), false);
Log.AddMultilineMessage(string.Format("Password:{0}", Password), false);
Log.EndMultilineMessage();
try
{
await AttemptLoginAsync();
}
catch
{
throw;
}
}
private async Task AttemptLoginAsync()
{
using (Pop3Client Client = new Pop3Client())
{
try
{
Client.Connect(HostName, Port, UseSss);
Client.Authenticate(UserName, Password);
}
catch
{
Log.AddMessage("Failed in AttemptAsync");
throw;
}
}
Teraz kilka pytań związanych z powyższym kodem:
Dane logowania zostały dobrane tak by kod na pewno zawiódł
- Metoda AttemptLoginAsync() jest wywoływana poprzez await więc tworzony jest dla niej nowy wątek. Który wątek - głowny czy ten utworzony na potrzeby await wykona kod z obiektu Log (AddMessage) ?
2.Zakładając że AddMessage wywołuje zdarzenie LogChanged, który wątek wykona kod UI zawarty w metodzie subskrybującej to zdarzenie. Metoda jak napisałem wyżej jest w klasie UI i wykonuje typowo operacje związane z obsługą UI.
-
Chciałem zosragnizować god w taki spsoób by najpierw wyświetlały się infromacje związane sposobem logowania (początek metody AttemptLogin) a dopiero potem po zalogowaniu się na serwer (co zajmuje trochę czasu) był wyświetlany komunikat o powodzeniu. Niestety tak się nie dzieje - wyświetla się wszytsko na raz po odczekaniu na zalogowanie.
-
Application.Run(Form1()) zgłasza wyjątek TargetInvocationException {"Obiekt docelowy wywołania zgłosił wyjątek."}
To mój pierwszy rproigram wielowątkowy więc prosiłbym o rozwianie moich wątpliwości.