Saya memiliki sedikit kode yang harus saya jalankan di utas yang berbeda dari GUI karena saat ini menyebabkan formulir membeku sementara kode berjalan (sekitar 10 detik).
Asumsikan saya belum pernah membuat utas baru sebelumnya; apa contoh sederhana / dasar tentang bagaimana melakukan ini di C # dan menggunakan .NET Framework 2.0 atau yang lebih baru?
c#
.net
multithreading
p.campbell
sumber
sumber
Jawaban:
Tempat yang baik untuk mulai membaca adalah Joe Albahari .
Jika Anda ingin membuat utas sendiri, ini sesederhana mungkin:
sumber
IsBackground
menjadi true. Mungkin tidak melakukan apa yang Anda pikirkan. Apa yang dilakukannya, adalah mengonfigurasi apakah utas akan dimatikan ketika semua utas depan telah mati, atau apakah utas akan membuat aplikasi tetap hidup. Jika Anda tidak ingin utas Anda dihentikan pada pertengahan eksekusi, jangan setelIsBackground
ke true.BackgroundWorker
tampaknya menjadi pilihan terbaik untuk Anda.Inilah contoh minimal saya. Setelah Anda mengklik tombol pekerja latar akan mulai bekerja di utas latar dan juga melaporkan kemajuannya secara bersamaan. Ini juga akan melaporkan setelah pekerjaan selesai.
catatan:
ProgressChanged
atauRunWorkerCompleted
penangan. Namun, memperbarui GUI dariDoWork
akan menyebabkanInvalidOperationException
.sumber
The ThreadPool.QueueUserWorkItem cukup ideal untuk sesuatu yang sederhana. Satu-satunya peringatan adalah mengakses kontrol dari utas lainnya.
sumber
Cepat dan kotor, tetapi akan berhasil:
Menggunakan di atas:
kode sederhana:
Saya baru saja melemparkan ini ke aplikasi konsol baru untuk exmaple
sumber
Berikut ini pilihan lain:
sumber
Coba gunakan kelas BackgroundWorker . Anda memberinya delegasi untuk apa yang harus dijalankan, dan untuk diberitahu ketika pekerjaan telah selesai. Ada contoh di halaman MSDN yang saya tautkan.
sumber
Jika Anda ingin mendapatkan nilai:
sumber
Letakkan kode itu dalam suatu fungsi (kode yang tidak bisa dieksekusi di utas yang sama dengan GUI), dan untuk memicu eksekusi kode itu, letakkan yang berikut ini.
Thread myThread= new Thread(nameOfFunction);
workerThread.Start();
Memanggil fungsi mulai pada objek utas akan menyebabkan pelaksanaan panggilan fungsi Anda di utas baru.
sumber
nameOfFunction
di latar belakang, dan bukan pada utas GUI saat ini. TheIsBackground
properti menentukan apakah benang akan tetap aplikasi hidup atau tidak: msdn.microsoft.com/en-us/library/...Di sini bagaimana caranya menggunakan utas dengan progressBar, itu hanya untuk menggarisbawahi cara kerja utas, dalam bentuk ada tiga tombol progressBar dan 4:
sumber
Charles kode Anda (di atas) tidak benar. Anda tidak perlu berputar menunggu sampai selesai. EndInvoke akan memblokir hingga WaitHandle diberi sinyal.
Jika Anda ingin memblokir hingga selesai, Anda hanya perlu melakukannya
atau sebagai alternatif
Tapi apa gunanya mengeluarkan panggilan telepon jika Anda memblokir? Anda mungkin juga hanya menggunakan panggilan sinkron. Taruhan yang lebih baik adalah dengan tidak memblokir dan meneruskan lambda untuk pembersihan:
Satu hal yang perlu diingat adalah Anda harus menelepon EndInvoke. Banyak orang lupa ini dan akhirnya membocorkan WaitHandle karena kebanyakan implementasi async melepaskan waithandle di EndInvoke.
sumber
Jika Anda akan menggunakan objek Thread mentah maka Anda harus mengatur IsBackground menjadi true minimum dan Anda juga harus mengatur model Threading Apartment (mungkin STA).
Saya akan merekomendasikan kelas BackgroundWorker jika Anda memerlukan interaksi UI.
sumber
opsi lain, yang menggunakan delegasi dan Thread Pool ...
dengan asumsi 'GetEnergyUsage' adalah metode yang mengambil DateTime dan DateTime lain sebagai argumen input, dan mengembalikan ...
sumber
int usageCnt = nrgDel.Invoke(lastRunTime, procDT, null, null);
? Sepertinya itu menangguhkan utas saat ini dengan tidur ... Saya pikir itu tidak akan membantu apa pun dengan pembekuan GUI jika Anda menyebutnya di utas GUIAda banyak cara menjalankan utas terpisah di .Net, masing-masing memiliki perilaku yang berbeda. Apakah Anda perlu terus menjalankan utas setelah GUI berhenti? Apakah Anda perlu menyampaikan informasi antara utas dan GUI? Apakah utas perlu memperbarui GUI? Haruskah utas melakukan satu tugas kemudian berhenti, atau haruskah terus berjalan? Jawaban atas pertanyaan-pertanyaan ini akan memberi tahu Anda metode mana yang digunakan.
Ada artikel metode async yang bagus di situs web Proyek Code yang menjelaskan berbagai metode dan memberikan kode sampel.
Catatan artikel ini ditulis sebelum pola async / await dan Task Parallel Library diperkenalkan ke .NET.
sumber
Cara: Gunakan Thread Latar Belakang untuk Mencari File
Anda harus sangat berhati-hati dengan akses dari utas lain ke hal-hal spesifik GUI (ini umum untuk banyak toolkit GUI). Jika Anda ingin memperbarui sesuatu dalam GUI dari pemrosesan utas, periksa jawaban ini yang menurut saya berguna untuk WinForms. Untuk WPF lihat ini (ini menunjukkan bagaimana menyentuh komponen dalam metode UpdateProgress () sehingga akan bekerja dari utas lainnya, tapi sebenarnya saya tidak suka itu tidak dilakukan
CheckAccess()
sebelum melakukanBeginInvoke
melalui Dispathcer, lihat dan cari CheckAccess di dalamnya)Sedang mencari .NET buku khusus tentang threading dan menemukan ini (dapat diunduh gratis). Lihat http://www.albahari.com/threading/ untuk perincian lebih lanjut tentang itu.
Saya yakin Anda akan menemukan apa yang Anda butuhkan untuk menjalankan eksekusi sebagai utas baru di 20 halaman pertama dan memiliki lebih banyak (tidak yakin tentang cuplikan khusus GUI yang saya maksud khusus untuk threading). Senang mendengar apa pendapat masyarakat tentang pekerjaan ini karena saya membaca yang ini. Untuk sekarang tampak cukup rapi untuk saya (untuk menunjukkan metode dan jenis NET spesifik untuk threading). Juga mencakup .NET 2.0 (dan bukan 1.1 kuno) apa yang saya sangat hargai.
sumber
Saya akan merekomendasikan melihat Power Threading Library milik Jeff Richter dan khususnya IAsyncEnumerator. Lihatlah videonya di Charlie Calvert's blog mana Richter memeriksanya untuk ikhtisar yang bagus.
Jangan menunda namanya karena itu membuat tugas pemrograman yang tidak sinkron lebih mudah dikodekan.
sumber