Це "Неправильно" / Погана конструкція, щоб перетворити нитку / фонового працівника в клас?


15

У мене є клас, який буде читати з Excel (C # і .Net 4), і в цьому класі я маю фонового працівника, який завантажуватиме дані з Excel, поки інтерфейс користувача може залишатися чуйним. Моє запитання таке: чи поганий дизайн мати фонового працівника в класі? Чи повинен я створити свій клас без нього і використовувати фонового працівника для роботи над цим класом? Я не можу бачити жодних проблем щодо створення свого класу таким чином, але потім я знову новачок, тому я зрозумів, що переконаюся, перш ніж продовжувати.

Я сподіваюся, що це питання є актуальним тут, оскільки я не думаю, що він повинен бути на стаковому потоці, оскільки працює мій код, це лише проблема дизайну.


3
чому ти вважаєш, що це може бути неправильно?
Альб

1
@Alb - важко сказати. Мій код працює і задовольняє мої потреби, проте я планую використовувати це в проекті, який буду робити з відкритим кодом. Я хочу переконатися, що мій код не просто працює, а насправді добре розроблений.
Jetti

Відповіді:


21

Чи повинен я створити свій клас без нього і використовувати фонового працівника для роботи над цим класом?

Так, слід. І я вам скажу, чому ви порушуєте Принцип єдиної відповідальності . Жорстко з'єднавши клас, який звертається до excel doc, з тим, як він отримує доступ до excel doc, ви усуваєте можливість для "контролера" коду (будь-якого коду, який це використовує) робити це по-іншому. Наскільки різні, ви можете запитати? Що робити, якщо код контролера має дві операції, які потребують тривалого часу, але хочуть, щоб вони були послідовними? Якщо ви дозволили контролеру обробляти нитки, він може виконувати обидві тривалі завдання разом в один потік. Що робити, якщо ви хочете отримати доступ до документа excel з контексту, що не є інтерфейсом користувача, і не потрібно, щоб він був потоковим?

Перекладаючи відповідальність за виведення потоку на абонента, ви досягаєте більшої гнучкості коду, роблячи його більш багаторазовим.


2
+1 для відповіді на актуальне запитання та відповіді на нього.
Адам Лір

+1 - Дякую Немі. Ви відповіли на моє запитання, я ціную це. Я витягну це з мого класу і поставлю його в новий клас, ще раз дякую!
Jetti

@Nemi - тож було б прийнятно, якби я створив інший метод, який би синхронізував завантаження, а потім мав би метод асинхронізації? Або просто краще мати один метод синхронного навантаження, а потім піти звідти?
Jetti

1
У мене особисто не було б методу синхронізації та методу асинхронізації. Ви все ще пов’язуєте обов'язки. Я багато разів працював з цією проблемою. Що я зробив, було створено TaskController, який моделювався за SwingWorker, але мав конкретний код для нашого додатка. TaskController робив такі дії, як оновлення панелі прогресу, зміна курсору миші тощо. Може здатися, що код пластини котла завжди повинен створювати TaskController для здійснення дзвінків, але в кінцевому рахунку код є більш надійним і більш доступним.
Nemi

Дякую Немі! Мені б хотілося, щоб я знову звернувся до вас, тому що ви обов'язково відповіли на моє запитання і вказали мені в правильному напрямку. Ще раз дякую вам!!
Jetti

3

Добре розробити, щоб операції з інтерфейсом працювали в окремій потоці від фонових завдань. В іншому випадку користувальницький інтерфейс стає невідповідним, коли програма зайнята.

Якщо ви зможете відокремити частину, яка працює у фоновій нитці, до власного класу, код буде чистішим.


1
Хоча правильно, з того, як я читаю його запитання, у нього немає проблеми з розумінням цього пункту.
Немі

Вибачте, якщо моє запитання було непрочитано. Я знаю, що розділення інтерфейсу користувача та фонових завдань - це гарний дизайн (якщо немає необхідності, мій тестовий файл excel перевищує 8 к рядків, і програма зробить програму невідповідною). В основному моє запитання: чи добре щільно з'єднати нитку з класом Excel.
Jetti

0

Я б відокремив ваш інтерфейс користувача від вашого основного завдання, використовуючи окремі класи. Це сприяє роз'єднанню проблем. Код інтерфейсу та логіка бізнесу не повинні змішуватися.


Щоб було зрозуміло, мій клас не торкається інтерфейсу користувача. У ньому є два події, які дозволять будь-якому використанню його оновити інтерфейс користувача, якщо це необхідно, але мій клас сам по собі не торкається інтерфейсу користувача.
Jetti

0

З того, що я пам'ятаю про BackgroundWorkers, це те, що вони надають ряд методів зручності, наприклад, можливість надсилати оновлення прогресу до інтерфейсу користувача. Не існує жодного правила, яке говорить, що ви не можете використовувати його з іншого класу.

Крім того, якщо ви робите ітерацію, яка не потребує обробці елементів у певному порядку, замість цього скористайтеся ThreadPool (або якщо ви користуєтесь .NET 4, використовуйте бібліотеку паралельних завдань ).


Дякую за Вашу відповідь. Я створив у своєму класі два події, які спричинять прогрес (в основному завершує подію прогресу BackgroundWorker, оскільки BackgroundWorker є приватним), який посилає прогрес до інтерфейсу користувача (панелі прогресу).
Jetti
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.