Обработка исключений в WinForm - PullRequest
3 голосов
/ 31 июля 2011

Я новичок в программировании на C #.Я столкнулся с небольшой проблемой при создании приложения с помощью формы.Я постараюсь объяснить это должным образом в рамках моих способностей и опыта.Проблема произошла, когда я попытался обработать исключение, вызванное Class1, созданным в моей Форме1.Допустим, у меня есть функция "public int Calc (int a, int b)" в Class1.В Form1 я создал этот класс для вызова его функции «Calc».Если я хочу сообщить об ошибке (например, делится на ноль), я должен обернуть вызов функции в элементы try / catch:

// Form1:

Class1 C1 = new Class1();
int a = 5;
int b = 0;
int c = 0;

try{
   c = C1.Calc(a,b)
}
catch(DivideByZeroException e)
{
   // some error handling code
}

... я думаюэтот пример не является надлежащей техникой ООП, поэтому мне пришлось решить поместить элементы try / catch непосредственно в Class1:

// Class1:

public int Calc(int a, int b)
{
    int c = 0;
    try{
      c = a/b;
    }
    catch(DivideByZeroException e)
    {
      // .........
    }
    return c;
}

... вопрос в том, как я могуполучить сообщение (DivideByZeroException e) в мою форму Form1, чтобы иметь возможность обработать его и отправить сообщение.Я не хочу создавать некоторую статическую функцию в Form1 только для того, чтобы достичь в ней класса MessageBox из Class1, потому что она не имеет смысла с точки зрения надлежащей функциональности ООП и возможности повторного использования Class1.Я читал о событиях и делегатах (я понимаю, что это простой указатель на функцию, аналогичную C ++), но это несколько сбивает с толку, и я не смог применить эту технику в своем коде.Не могли бы вы написать простой пример, который укажет мне правильное направление.

спасибо, ребята

Cembo

Ответы [ 5 ]

7 голосов
/ 31 июля 2011

Правильная техника действительно первая. Если вы не можете справиться с этим внутри своей функции, то у вас нет никаких попыток. Поместите обработку исключений в место, где исключение может быть обработано, и программа может продолжить (или завершить работу корректно), и пользователь будет уведомлен об ошибке соответствующим образом.

2 голосов
/ 31 июля 2011

Я предлагаю вам внедрить следующий код в ваше приложение внутри файла Program.cs

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());

        // -----------------
        Application.ThreadException += Application_ThreadException;
        // -----------------
    }

    static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
    {
        // Handle your exception here...
        MessageBox.Show(string.Format("There is an error\n{0}", e.Exception.Message));
    }

это поймает ваше необработанное исключение во всем приложении.

1 голос
/ 31 июля 2011

Для того, чтобы он попадал в область действия вызывающего пользовательского интерфейса, вам нужно будет сгенерировать исключение после того, как оно было перехвачено, или, что еще лучше, не выбрасывать его вообще - поскольку деление на ноль вызовет бросок CLRисключение при необходимости.Здесь можно выполнить простые проверки, в то время как Calc вызов API может по-прежнему выдавать исключение.

Например, просто проверьте данные перед вызовом Calc:

if (a > 0 && b > 0)
{
    var result = Calc(a, b);
}
else 
{
    //tell the user to input valid data
}

В методе Calc вы можете выполнить аналогичную проверку и сгенерировать соответствующее исключение:

public int Calc(int a, int b)
{
    if (a <= 0) throw new ArgumentException("appropriate message here");
    if (b <= 0) throw new ArgumentException("appropriate message here");
    ...
}

Идея здесь состоит в том, чтобы предотвратить деление на ноль, но это может быть немного чрезмернымв вашем случае, как показывает предыдущий пример, вы можете по существу обеспечить такое же поведение, однако теперь вам нужно перехватить исключение:

try
{
    var result = Calc(a, b);
}
catch //use appropriate exception catches
{
     //tell the user to input valid data
}
0 голосов
/ 31 июля 2011
public int Calc(int a, int b)
    {
        int c = a/b;
    }

Оставьте это простым и понятным с необходимой вам логикой.

Затем обработайте ошибку в форме так, как вы это делали.

0 голосов
/ 31 июля 2011

Одним простым способом может быть изменение вашего метода на что-то вроде этого

public int Calc(int a, int b, out string error)
{
    error = string.empty;
    int c = 0;
    try
    {
      c = a/b;
    }
    catch(DivideByZeroException e)
    {
         error = e.ToString();
    }
    return c;
}

Теперь в вызывающей программе вы можете проверить

string error; 
int res = Calc( 1, 2, out error);
if(!string.isnullorempty(error)
{
    //error has occured
    messagebox.show(error);
}
else
{
    //no error
    // you can proceed noramlly
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...