Re[8]: [winforms][exception]Оформление оформление обработчиков событий
От: VladCore  
Дата: 30.09.16 19:19
Оценка: +1 :)
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, VladCore, Вы писали:


VC>>Идемпотентность на UI?

S>В бизлогике, топик читайте У топикстартера из кода формы выполняется "Открытие отчёта такого-то за такой-то период"...

понял, бизлогика в Button.Click
Re[3]: [winforms][exception]Оформление оформление обработчиков событий
От: Sinix  
Дата: 29.09.16 10:02
Оценка: 1 (1)
Здравствуйте, nikda, Вы писали:

N>"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то"

Если есть желание извратиться с исключениями — чем nested exceptions не подходят?

Вызывающий код оформляем в
TryDo("SomeOpMessage", ()=>
{
  // your code here
})
, работает
Re: [winforms][exception]Оформление оформление обработчиков событий
От: Vasiliy2  
Дата: 29.09.16 10:59
Оценка: +1
Здравствуйте, nikda, Вы писали:

N>При работе с WinForms получается куча обработчиков различных WinForms-событий.

N>Шаблон кода почти у всех одинаковый (см. ниже)
N>Есть ли хороший способ уйти от дублирования кода?

Перейти на шаблон проектирования UI MVP. Использовать View как источник первичной информации от пользователя, проводить нужные проверки через презентер в модели, при необходимости общаться через события.

Отображать информационные сообщения типа "Открытие отчёта такого-то за такой-то период" через исключения считаю не правильным. Но если очень хочется, то Sinix правильно подсказал
Автор: Sinix
Дата: 29.09.16
[winforms][exception]Оформление оформление обработчиков событий
От: nikda  
Дата: 29.09.16 07:43
Оценка:
При работе с WinForms получается куча обработчиков различных WinForms-событий.
Шаблон кода почти у всех одинаковый (см. ниже)
Есть ли хороший способ уйти от дублирования кода?


  private void Button1_Click(x,y,z)
  {
    try
    {
       // some actions
       // ...
       throw new Exception();
       // ...       
    }
    catch(Exception ex)
    {
      ShowErrorForUser(ex.Message);
    }
  }

  private void Button2_Click(x,y,z)
  {
    try
    {
       // some actions
       // ...
       throw new Exception();
       // ...       
    }
    catch(Exception ex)
    {
      ShowErrorForUser(ex.Message);
    }
  }
  
  //..
  
  private void ButtonN_Click(x,y,z,d,e)
  {
    try
    {
       // some actions
       // ...
       throw new Exception();
       // ...       
    }
    catch(Exception ex)
    {    
      ShowErrorForUser(ex.Message + "Some text");
      DoSomeOtherAction();
    }
  }
Re: [winforms][exception]Оформление оформление обработчиков событий
От: Sinix  
Дата: 29.09.16 08:06
Оценка:
Здравствуйте, nikda, Вы писали:

N>При работе с WinForms получается куча обработчиков различных WinForms-событий.

N>Шаблон кода почти у всех одинаковый (см. ниже)
N>Есть ли хороший способ уйти от дублирования кода?

1. По возможности не бросать исключения для выдачи сообщений пользователю.
2. Навесить свою форму на Application.ThreadException event.
Re: [winforms][exception]Оформление оформление обработчиков
От: Карбофос  
Дата: 29.09.16 08:41
Оценка:
Здравствуйте, nikda, Вы писали:

N>При работе с WinForms получается куча обработчиков различных WinForms-событий.

N>Шаблон кода почти у всех одинаковый (см. ниже)
N>Есть ли хороший способ уйти от дублирования кода?


N>
N>  private void Button1_Click(x,y,z)
N>  {
N>    try
N>    {
N>       // some actions
N>       // ...
N>       throw new Exception();
N>       // ...       
N>    }
N>    catch(Exception ex)
N>    {
N>      ShowErrorForUser(ex.Message);
N>    }
N>  }

N>  private void Button2_Click(x,y,z)
N>  {
N>    try
N>    {
N>       // some actions
N>       // ...
N>       throw new Exception();
N>       // ...       
N>    }
N>    catch(Exception ex)
N>    {
N>      ShowErrorForUser(ex.Message);
N>    }
N>  }
  
N>  //..
  
N>  private void ButtonN_Click(x,y,z,d,e)
N>  {
N>    try
N>    {
N>       // some actions
N>       // ...
N>       throw new Exception();
N>       // ...       
N>    }
N>    catch(Exception ex)
N>    {    
N>      ShowErrorForUser(ex.Message + "Some text");
N>      DoSomeOtherAction();
N>    }
N>  }
N>

1. У событий есть параметр sender
2. У контролов есть свойство Tag
...
button1.Tag = new MyParam(x1,y1,z1);
button2.Tag = new MyParam(x2,y2,z2);
...
button1.Click += anybutton_click;
button2.Click += anybutton_click;
...
void anybutton_click(object sender, ...)
{
  var tag = (sender as Control).Tag;
  if (tag is MyParam)
  {
    DoSomething(tag as MyParam);
  }
}

private void DoSomething(MyParam p)
{
  try
  {
    ...
  }
  catch(Exception ex)
  {    
    ShowErrorForUser(ex.Message + "Some text");
    DoSomeOtherAction();
  }
}

А если чисто исключения все заворачивать, то это ИМХО вообще не в тему. исключения — они не для пользователей и их нужно обрабатывать по месту.
Отредактировано 29.09.2016 8:43 Карбофос . Предыдущая версия .
Re[2]: [winforms][exception]Оформление оформление обработчиков событий
От: nikda  
Дата: 29.09.16 09:56
Оценка:
Здравствуйте, Sinix, Вы писали:

S>1. По возможности не бросать исключения для выдачи сообщений пользователю.


S>2. Навесить свою форму на Application.ThreadException event.


OK. Допустим нужно добавить в сообщение Exception дополнительную информацию, например:
"Открытие отчёта такого-то за такой-то период".

Можно сделать навесив атрибут на метод и в Application.ThreadException определить его по targetSite — но этот способ подходит только для статических строк.
А если нужно добавить более подробные данные, например очередной "шаг" в методе или введённые пользователем данные.
Exception можно получить, например при проверке данных, которые вернула база. И в итоге нужно увидеть на экране сообщение об ошибке:

"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то"
Re[4]: [winforms][exception]Оформление оформление обработчиков событий
От: nikda  
Дата: 29.09.16 11:48
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, nikda, Вы писали:


N>>"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то"

S>Если есть желание извратиться с исключениями — чем nested exceptions не подходят?

S>Вызывающий код оформляем в

S>
S>TryDo("SomeOpMessage", ()=>
S>{
S>  // your code here
S>})
S>
, работает


1) Собственно так сейчас и есть. А необработанные исключения в — Application.ThreadException.
Но понравился вариант все обработать в Application.ThreadException, что бы не засорять код.

2) Понятно, что показывать пользователю технические/логические подробности ошибки не нужно (не обязательно).
Но в лог всё равно должно уйти подробное сообщение. Например, если получили от базы что-то не то или база вернула ошибку, нужно дополнить сообщение в логе не только самой ошибкой, но и например как до неё дошли: шаг в методе, ввод пользователя.

3) Или есть другой более правильный способ?
Re[2]: [winforms][exception]Оформление оформление обработчиков событий
От: nikda  
Дата: 29.09.16 11:50
Оценка:
Здравствуйте, Vasiliy2, Вы писали:

V>Здравствуйте, nikda, Вы писали:


N>>При работе с WinForms получается куча обработчиков различных WinForms-событий.

N>>Шаблон кода почти у всех одинаковый (см. ниже)
N>>Есть ли хороший способ уйти от дублирования кода?

V>Перейти на шаблон проектирования UI MVP. Использовать View как источник первичной информации от пользователя, проводить нужные проверки через презентер в модели, при необходимости общаться через события.


Просто код из формы перейдёт в презентер и там будут такие же обёртка try/catch для всех методов, реализующих реакцию на события от пользователя.
Re[3]: [winforms][exception]Оформление оформление обработчиков событий
От: Vasiliy2  
Дата: 29.09.16 12:49
Оценка:
Здравствуйте, nikda, Вы писали:


N>Просто код из формы перейдёт в презентер и там будут такие же обёртка try/catch для всех методов, реализующих реакцию на события от пользователя.

Принципиально — да, согласен — простое перемещение просто идет из формы в презентер. Но здесь уже надо смотреть как вообще строить систему обработки исключений. Если она уже выстроена, то сильно не разгонишься.
Обрабатывать все в Application.ThreadException — я не уверен что это лучшая идея в плане того, что если исключение обработано не по месту, приложение может находится в несогласованном состоянии, когда некоторым данным уже доверять нельзя.
Есть вариант — выстроить систему обработки по слоям, например в модели обрабатывать нужные исключения и в PL пробрасывать событие. Здесь правда, при неправильной организации можно нарваться на то, что некоторые исключения могут быть случайно скрыты.
Re[4]: [winforms][exception]Оформление оформление обработчиков событий
От: VladCore  
Дата: 30.09.16 15:10
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, nikda, Вы писали:


N>>"При Открытии отчёта такого-то за такой-то период база данных вернула ошибку такую-то"

S>Если есть желание извратиться с исключениями — чем nested exceptions не подходят?

S>Вызывающий код оформляем в

S>
S>TryDo("SomeOpMessage", ()=>
S>{
S>  // your code here
S>)
S>



Ты или забыл зачем катч нужен — восстановить состояние UI из неконсистентного в консистентного.

Или просто прикалываешься?

В каждой операции и в общем случае действия для восстановления разные, и у топикстартера разные. так что оформлять тебе придется так:

S>
S>TryDo("SomeOpMessage", ()=>
S>{
S>  // your code here
S>}, (exception)=>
S>{
S>  // your recovery code here
S>})
S>


Re[5]: [winforms][exception]Оформление оформление обработчиков событий
От: Sinix  
Дата: 30.09.16 15:47
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>Или просто прикалываешься?

Не прикалываюсь, в подобных хелперах код по определению подразумевается атомарным (а в особо запущенных случаях с retry — ещё и идемпотентным), восстановление состояния — ответственность кода, а не собственно хелпера.

У нас за подобные штуки отвечает система локальных транзакций, т.е. откат работает автоматом. Без неё метод лучше бы обозвать как DoOperation();
Re[6]: [winforms][exception]Оформление оформление обработчиков событий
От: VladCore  
Дата: 30.09.16 16:20
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, VladCore, Вы писали:


VC>>Или просто прикалываешься?

S>Не прикалываюсь, в подобных хелперах код по определению подразумевается атомарным (а в особо запущенных случаях с retry — ещё и идемпотентным), восстановление состояния — ответственность кода, а не собственно хелпера.

Идемпотентность на UI? Нуну. Хотя вдруг пользователь вда раза кнопку нажал. Надо проверить
Re[7]: [winforms][exception]Оформление оформление обработчиков событий
От: Sinix  
Дата: 30.09.16 16:37
Оценка:
Здравствуйте, VladCore, Вы писали:

VC>Идемпотентность на UI?

В бизлогике, топик читайте У топикстартера из кода формы выполняется "Открытие отчёта такого-то за такой-то период"...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.