Можете ли вы прервать процедуру набора свойств - PullRequest
3 голосов
/ 17 февраля 2010

Я программирую на C # .NET. Можно отменить заданную процедуру свойства класса, не вызывая исключение?

Вот что я хочу сделать ...

public int RandomProperty
{
    set
    {
     DialogResult answer = new DialogResult();
     answer = MessageBox.Show("This process could take up to 5 min. Are you sure you want to continue?");
     if(answer = DialogResult.No) 
        CancelSet   // Can I do something similar here?
     else
     {
      ...Do set procedure
     }
    }
}

Я не думаю, что могу использовать метод (вместо свойства), потому что я устанавливаю это значение с помощью таблицы свойств.

Ответы [ 5 ]

12 голосов
/ 17 февраля 2010

ИМО, что просто нехорошо делать - ожидание таково, что если set не выбрасывает, ему присваивается значение. Протестируйте в пользовательском интерфейсе (или где-либо) перед , выполнив set, или сгенерируйте и обработайте исключение. В качестве альтернативы, вызывающий может быть менее запутанным методом:

public bool TrySetRandomProperty(SomeType value) {
    ...
}

, который возвращает true или false, чтобы указать, произошло ли это. Вам также следует избегать попадания кода пользовательского интерфейса в доменную логику; возможно, использовать событие, чтобы пользовательский интерфейс мог общаться с пользователем, не вызывая определенную реализацию пользовательского интерфейса для вызывающего абонента?

8 голосов
/ 17 февраля 2010

Ни при каких обстоятельствах вы не должны делать ничего из этого. Свойство всегда должно быть fast и логически представлять свойство чего-либо. В идеале это никогда не должно подвести. Это, конечно, не должно вызывать побочных эффектов, таких как появление пользовательского интерфейса. Вы нарушаете все эти важные правила. Не делай этого.

Кроме того, ваш дизайн интерфейса плохой. Не спрашивайте пользователя заранее "это может занять некоторое время, вы уверены?" а затем накажи их долгим ожиданием, если они нажмут "да". Вместо этого запустите операцию и, если она не вернется быстро, откройте элемент пользовательского интерфейса, который показывает индикатор выполнения и приблизительное оставшееся время с кнопкой отмены.

Вероятно, вы должны написать свою длительную операцию как асинхронный метод, который можно полностью отменить в другом потоке.

Хорошая архитектура для такого рода вещей состоит в том, чтобы ваш метод немедленно возвращал объект, который выставляет события типа «Я все еще бегу, и вот как далеко я впереди», или «Я закончил сейчас, и вот результат "или" Я получил ошибку при попытке выполнить операцию, и вот что это такое ". Этот объект также может предоставлять метод «отмена», который знает, как взаимодействовать с рабочим потоком и правильно его закрывать. Вызывающий метод, который получает этот объект, может затем решить, как отобразить пользовательский интерфейс для пользователя.

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

3 голосов
/ 17 февраля 2010

Тьфу. Вы действительно хотите задействовать пользовательский интерфейс внутри свойства класса? Разве вы не должны делать эту проверку дальше в пользовательском интерфейсе?

2 голосов
/ 17 февраля 2010

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

Однако у вас очень плохой дизайн, когда вы смешиваете пользовательский интерфейс с низкоуровневым кодом.

Задать вопрос перед установкой свойства можно одним из вариантов.

1 голос
/ 17 февраля 2010

Просто вернитесь из набора.Вам нужно будет использовать личное поле для хранения значения того, что вы хотите установить, но возвращение в «отмена» должно сделать это.

...