wyjątek nie kończy aplikacji

0

Taki dość dziwny problem:

public Form1
{Excel.Worksheet objSheet;
naciśniecie_przycisku()
{try
{objSheet = (Excel.Worksheet)objSheets.get_Item("Sheet1");
}
cache
{komunikat o błędzie
System.Windows.Forms.Application.Exit();
}
dalsze działanie
}
}

Nie działa, mimo, że kod z cache jest "mielony". Program po prostu wychodzi z cache i wykonuje się dalej zgodnie z instrukcjami, co powoduje wkrótce błąd i wywalenie.
Natomiast:

public Form1
{naciśniecie_przycisku()
{try
{Excel.Worksheet objSheet = (Excel.Worksheet)objSheets.get_Item("Sheet1");
}
cache
{komunikat o błędzie
System.Windows.Forms.Application.Exit();
}
dalsze działanie
}
}

Działa jak najbardziej. Dlaczego się tak dzieje?

Wolałbym pierwszą wersję, żeby nie zagnieżdżać wyjątków (bo będzie ich kilka) i przede wszystkim dla tego, że dla wygody kilka zmiennych chciałbym uczynić globalnymi.

Pozdrawiam.

0

Daj pelny kod sekcji catch, bo najwyrazniej cos tam jest nie tak. Po drugie 'catch', nie 'cache'...

0

No tak, błąd faktycznie: zamiast "cache" powinno być "catch".
Pełny kod:

public partial class Form1 : Form
{Excel.Application objApp = new Excel.Application();
dodatkowo są jeszcze w tymże miejscu:
Excel.Workbook objBook;
Excel.Sheets objSheets;
Excel.Worksheet objSheet;*/

......

public Form1()
{.....}

private void buttonOpenFile_Click(object sender, EventArgs e)
{
if(czy plik został wybrany)
{ //jeśli tak to
.....
try
    {objSheet = (Excel.Worksheet)objSheets.get_Item("Sheet1");
    }
catch   
    {MessageBox.Show("This file dosn't contains sheet called \"Sheet1\"!\nChange structure of this file or choose other one.", "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
    Application.Exit();
    }
..... tu jest kod (dowolny - cokolwiek wpiszę - który się wykonuje, mimo że aplikacja "została" zakończona"....
}
}

I ta wersja nie działa. Po tym jak zadeklaruję i zainicjuję objSheet w try, a nie tam gdzie teraz, wszystko jest ok. POszperałem trochę po forumach i spotkałem się z tym problemem, ale nikt nie dał rozwiązania.

0

Sprobuj dac tak:


{
MessageBox.Show(...);
MessageBox.Show("komunikat testowy");
Application.Exit();
}
MessageBox.Show("ten komunikat nie powinien sie pokazac");



i napisz jakie komunikaty wychodza.

Co wiecej:

 > ##### msdn napisał(a)
> The Exit method stops all running message loops on all threads and closes all windows of the application. <b>This method does not necessarily force the application to exit</b>. The Exit method is typically called from within a message loop, and forces Run to return. To exit a message loop for the current thread only, call ExitThread.
0

Rozumiem, że twoje instrukcje dotyczą ciała catch.
Wcześniej już próbowałem. Niestety nic to nie daje.
Taka wersja powoduje to, że ""ten komunikat nie powinien sie pokazac" się nie pokazuje się, ale jeżeli jest jeszcze jakiś kod nie odwołujący się do żadnej kontrolki to on wykonuje się z całą pewnością. Sam messagebox nie generuje żadnych błędów, ani ostrzeżeń.
Z tego co zrozumiałem z inszych forów, to powodem takiego zachowania jest to, że nie wszystkie wątki danej aplikacji są "zabijane".
Co ciekawe, jak użyję Environment.Exit(), to aplikacja kończy działanie, ale niektórzy odradzali używanie tej funkcji ze względu na ew. problemy z prawami dostępu, których potrzebuje.
Jak rozumuję sprawa wygląda przejrzyście. Aplikacja zainicjowana na zewnątrz wyjątku nie jest kończona przez Application.Exit(), natomiast ta wewnątrz owszem. Niejasne są dla mnie tylko mechanizmy takiego działania. No i oczywiście nie znam rozwiązania.</image>

0

Mechanizm takiego dzialania jest dosc oczywisty. Application.Exit() nie zamyka brutalnie aplikacji, tylko informuje wszystkie zainteresowane watki, ze powinny przestac przyjmowac nowe komunikaty i zakonczyc swoje dzialanie. Ale jesli po Application.Exit() jeszcze cos jest, to zanim do watku dotrze, ze juz koniec petli komunikatow (message loop), to cos jeszcze moze przez sitko przejsc.

Dlatego zamkniecie nie jest gwarantowane - bo teoretycznie jak watek zwisnie, to aplikacja sie nie zamknie. Gdyz prosba o zamkniecie do niego nie dotrze.

Propozycja rozwiazania:
w sekcji catch ustawiaj jakas flage, ktora informuje o tym, ze aplikacja jest zamykana i po tym bloku wykonuj cokolwiek tylko jesli flaga nie jest ustawiona.

0

No, to się nazywa konkretnie i na temat.
Szczerze mówiąc to bym chyba na tak banalne wyjaśnienie nie wpadł. To są właśnie uroki programowania wielowątkowego :)
Pozdrawiam.

0

tak z ciekawości:

  1. śledziłeś wykonanie programu z debugerem w trybie krokowym? wchodził do sekcji catch?
  2. tworzysz własne wątki w programie?
  3. jeśli aplikacja uruchamiana jest w stylu "Application.Run(new Form1())", może wystarczyć dać w catchu zdisposować excelowe obiekty i wywołać Close() formularza?
0

Sprawdzałem sprawę krokowym debugerem. Catch jest wykonywany. Powiem więcej, nawet Application.Exit () jest wykonywana (w jakiś tam swój pokrętny sposób).
Cały znaczący kod aplikacji jest w przykładzie.
Aplikacji nie uruchamiam w ten sposób jaki podajesz.
Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0