Is It “Wrong” / Bad Design Untuk Meletakkan Thread / Pekerja Latar Belakang Di Kelas?

15

Saya memiliki kelas yang akan membaca dari Excel (C # dan .Net 4) dan di kelas itu saya memiliki pekerja latar belakang yang akan memuat data dari Excel sementara UI dapat tetap responsif. Pertanyaan saya adalah sebagai berikut: Apakah desain yang buruk memiliki pekerja latar belakang di suatu kelas? Haruskah saya membuat kelas saya tanpa itu dan menggunakan pekerja latar belakang untuk beroperasi di kelas itu? Saya tidak bisa melihat masalah apa pun tentang membuat kelas saya dengan cara ini, tetapi sekali lagi saya seorang pemula jadi saya pikir saya akan memastikan sebelum melanjutkan.

Saya harap pertanyaan ini relevan di sini karena saya tidak berpikir itu harus di stackoverflow karena kode saya berfungsi, ini hanya masalah desain.

Jetti
sumber
3
mengapa Anda berpikir itu mungkin salah?
Alb
1
@ Alb - sulit untuk mengatakan. Kode saya berfungsi dan memenuhi kebutuhan saya, namun saya berencana menggunakan ini dalam proyek yang akan saya buat open source. Saya ingin memastikan bahwa kode saya tidak "berfungsi" dan sebenarnya dirancang dengan baik.
Jetti

Jawaban:

21

Haruskah saya membuat kelas saya tanpa itu dan menggunakan pekerja latar belakang untuk beroperasi di kelas itu?

Ya kamu harus. Dan saya akan memberi tahu Anda alasannya - Anda melanggar Prinsip Tanggung Jawab Tunggal . Dengan secara ketat menghubungkan kelas yang mengakses dokumen excel dengan cara mengakses dokumen excel, Anda menghilangkan kemampuan kode "controller" (kode apa pun yang menggunakan ini) untuk melakukannya dengan cara yang berbeda. Seberapa berbeda, Anda mungkin bertanya? Bagaimana jika kode pengontrol memiliki dua operasi yang memakan waktu lama tetapi menginginkannya berurutan? Jika Anda mengizinkan pengontrol untuk menangani threading, pengontrol dapat melakukan kedua tugas yang sudah berjalan lama dalam satu utas. Bagaimana jika Anda ingin mengakses dokumen excel dari konteks non-UI dan tidak perlu di-threaded?

Dengan memindahkan tanggung jawab untuk mengirim keluar ke pemanggil, Anda memungkinkan lebih banyak fleksibilitas kode Anda, membuatnya lebih dapat digunakan kembali.

Nemi
sumber
2
+1 untuk menjawab pertanyaan aktual yang diajukan dan menjawabnya dengan baik.
Adam Lear
+1 - Terima kasih Nemi. Anda menjawab pertanyaan saya langsung, saya menghargainya. Saya akan menariknya keluar dari kelas saya dan memasukkannya ke kelas baru, terima kasih lagi!
Jetti
@ Nemi - jadi apakah itu dapat diterima jika saya membuat metode lain yang akan memuat sinkron dan kemudian memiliki metode async? Atau akan lebih baik untuk memiliki satu metode beban sinkron dan kemudian pergi dari sana?
Jetti
1
Saya pribadi tidak akan memiliki metode sinkronisasi dan metode async. Anda masih memegang tanggung jawab. Saya telah bekerja dengan masalah persis ini berkali-kali. Apa yang saya lakukan adalah menciptakan TaskController yang dimodelkan setelah SwingWorker, tetapi memiliki kode khusus untuk aplikasi kami. TaskController melakukan hal-hal seperti memperbarui bilah kemajuan, mengubah kursor mouse, dll. Ini mungkin tampak seperti kode pelat ketel untuk selalu harus membuat TaskController untuk membuat panggilan, tetapi pada akhirnya kode lebih kuat dan lebih dapat dipertahankan.
Nemi
Nemi terima kasih! Saya berharap saya dapat memperbaiki Anda lagi karena Anda pasti menjawab pertanyaan saya dan mengarahkan saya ke arah yang benar. Terima kasih lagi!!
Jetti
3

Desain yang bagus agar operasi UI beroperasi di utas terpisah dari tugas latar belakang. Kalau tidak, UI menjadi tidak responsif ketika aplikasi sedang sibuk.

Jika Anda dapat memisahkan bagian yang berfungsi di utas latar belakang ke kelasnya sendiri, kodenya akan lebih bersih.

Alb
sumber
1
Meski benar, dari cara saya membaca pertanyaannya dia tidak memiliki masalah memahami hal ini.
Nemi
Maaf jika pertanyaan saya salah dibaca. Saya tahu bahwa memisahkan UI dan tugas-tugas latar belakang adalah desain yang baik (jika tidak perlu, file excel pengujian saya lebih dari 8k baris dan akan membuat program tampak tidak responsif). Pertanyaan saya pada dasarnya adalah apakah baik untuk memasangkan secara ketat topik dengan kelas Excel.
Jetti
0

Saya akan memisahkan UI Anda dari tugas latar belakang Anda menggunakan kelas yang terpisah. Melakukannya mendorong pemisahan kekhawatiran. Kode UI dan logika bisnis tidak boleh dicampur.

Ryan Michela
sumber
Supaya jelas, kelas saya tidak menyentuh UI. Ini memiliki dua peristiwa yang akan memungkinkan apa pun yang menggunakannya untuk memperbarui UI jika perlu, tetapi kelas saya sendiri tidak menyentuh UI.
Jetti
0

Dari apa yang saya ingat tentang BackgroundWorkers adalah bahwa mereka menyediakan sejumlah metode kenyamanan seperti kemampuan untuk mengirim pembaruan kemajuan ke UI. Tidak ada aturan yang mengatakan Anda tidak dapat menggunakannya dari kelas yang berbeda.

Juga jika Anda melakukan iterasi yang tidak mengharuskan item diproses dalam urutan tertentu, pertimbangkan untuk menggunakan ThreadPool sebagai gantinya (atau jika Anda menggunakan .NET 4 gunakan Pustaka Paralel Tugas ).

Michael Brown
sumber
Terimakasih atas tanggapan Anda. Saya membuat dua acara di kelas saya yang akan memicu kemajuan (pada dasarnya membungkus acara kemajuan BackgroundWorker, karena BackgroundWorker bersifat pribadi) yang mengirimkan kemajuan ke UI (progress bar).
Jetti