Ambil metode System.Windows.Forms.Control.Invoke (metode Delegasi)
Mengapa ini memberikan kesalahan waktu kompilasi:
string str = "woop";
Invoke(() => this.Text = str);
// Error: Cannot convert lambda expression to type 'System.Delegate'
// because it is not a delegate type
Namun ini berfungsi dengan baik:
string str = "woop";
Invoke((Action)(() => this.Text = str));
Kapan metode mengharapkan Delegasi biasa?
Invoke(()=>DoStuff)
dan masih mendapat kesalahan. Masalahnya adalah saya menggunakan 'ini' yang tersirat. Untuk mendapatkannya bekerja dari dalam anggota Kontrol Anda harus eksplisit:this.Invoke(()=>DoStuff)
.Bosan melempar lambda berulang kali?
sumber
Lambda<T>
kelas memiliki metode konversi identitas yang dipanggilCast
, yang mengembalikan apa pun yang diteruskan (Func<T, T>
). SekarangLambda<T>
dideklarasikan sebagaiLambda<Func<int, string>>
yang berarti jika Anda meneruskan metodeFunc<int, string>
keCast
, ituFunc<int, string>
kembali, karenaT
dalam kasus ini adalahFunc<int, string>
.Sembilan persepuluh dari waktu orang mendapatkan ini karena mereka mencoba untuk marshal ke thread UI. Inilah cara malas:
Sekarang setelah diketik, masalahnya hilang (qv Skeet's anwer) dan kami memiliki sintaks yang sangat ringkas ini:
Untuk poin bonus, inilah tip lainnya. Anda tidak akan melakukan ini untuk hal-hal UI tetapi dalam kasus di mana Anda memerlukan SomeMethod untuk memblokir hingga selesai (misalnya, permintaan / respons I / O, menunggu respons) gunakan WaitHandle (qv msdn WaitAll, WaitAny, WaitOne).
Perhatikan bahwa AutoResetEvent adalah turunan WaitHandle.
Dan tip terakhir karena hal-hal bisa menjadi kusut: WaitHandles menghentikan utas. Inilah yang seharusnya mereka lakukan. Jika Anda mencoba untuk melakukan marshal ke thread UI saat Anda menghentikannya , aplikasi Anda akan hang. Dalam kasus ini (a) beberapa pemfaktoran ulang serius sedang dilakukan, dan (b) sebagai peretasan sementara Anda dapat menunggu seperti ini:
sumber
System.Windows.Threading.Dispatcher.CurrentDispatcher
akan mengembalikan operator utas CURRENT - yaitu jika Anda memanggil metode ini dari utas yang bukan utas UI, kode tidak akan dijalankan pada utas UI.Peter Wone. kamu adalah seorang pria. Mengambil konsep Anda sedikit lebih jauh, saya menemukan dua fungsi ini.
Saya menempatkan dua fungsi ini ke dalam aplikasi Formulir saya, dan saya dapat melakukan panggilan dari pekerja latar belakang seperti ini
Mungkin agak malas, tetapi saya tidak perlu menyiapkan fungsi yang dikerjakan oleh pekerja, yang sangat berguna dalam kasus seperti ini
Pada dasarnya, dapatkan beberapa alamat ip dari Gui DataGridView, ping mereka, atur ikon yang dihasilkan menjadi hijau atau merah, dan aktifkan kembali tombol pada formulir. Ya, ini adalah "parallel.for" pada pekerja latar belakang. Ya, ini BANYAK meminta overhead, tetapi dapat diabaikan untuk daftar pendek, dan kode yang jauh lebih ringkas.
sumber
Saya mencoba membangun ini berdasarkan jawaban @Andrey Naumov . Mungkin ini sedikit perbaikan.
Di mana parameter tipe
S
adalah parameter formal (parameter input, yang minimum diperlukan untuk menyimpulkan tipe lainnya). Sekarang Anda bisa menyebutnya seperti:Anda dapat memiliki kelebihan beban tambahan untuk
Action<S>
danExpression<Action<S>>
serupa di kelas yang sama. Untuk lainnya dibangun dalam mendelegasikan dan ekspresi jenis, Anda akan harus menulis kelas terpisah sepertiLambda
,Lambda<S, T>
,Lambda<S, T, U>
dllKeuntungan dari ini saya lihat dari pendekatan aslinya:
Satu spesifikasi tipe yang lebih sedikit (hanya parameter formal yang perlu ditentukan).
Yang memberi Anda kebebasan untuk menggunakannya terhadap apa pun
Func<int, T>
, tidak hanya ketikaT
dikatakanstring
, seperti yang ditunjukkan dalam contoh.Mendukung ekspresi langsung. Dalam pendekatan sebelumnya Anda harus menentukan tipe lagi, seperti:
untuk ekspresi.
Memperluas kelas untuk tipe delegasi (dan ekspresi) lain juga merepotkan seperti di atas.
Dalam pendekatan saya, Anda harus mendeklarasikan tipe hanya sekali (itu terlalu satu kurang untuk
Func
s).Satu cara lain untuk mengimplementasikan jawaban Andrey adalah seperti tidak sepenuhnya generik
Jadi hal-hal berkurang menjadi:
Itu bahkan lebih sedikit mengetik, tetapi Anda kehilangan keamanan jenis tertentu, dan imo, ini tidak sepadan.
sumber
Agak terlambat ke pesta tetapi Anda juga bisa melakukan cast seperti ini
sumber
sumber
Bermain dengan XUnit dan Fluent Assertions adalah mungkin untuk menggunakan kemampuan inline ini dengan cara yang menurut saya sangat keren.
Sebelum
Setelah
sumber