Pertanyaan Penguncian sumber daya dengan async / menunggu


Saya memiliki aplikasi di mana saya memiliki sumber daya bersama (sistem Gerak) yang dapat diakses oleh banyak klien. Saya memiliki Operasi individu yang memerlukan akses ke sistem selama durasi pemindahan dan yang seharusnya membuang pengecualian 'Sibuk' jika operasi yang bertentangan diminta pada saat yang bersamaan. Saya juga memiliki Sequencer yang perlu mendapatkan akses eksklusif ke sistem Gerak untuk pelaksanaan beberapa Operasi, diselingi dengan tindakan lain; selama seluruh urutan, tidak ada klien lain yang dapat menjalankan Operasi.

Saya telah secara tradisional mendekati ini menggunakan Thread-afinitas, sehingga Thread dapat meminta akses eksklusif dan menjalankan memblokir panggilan yang sesuai dengan operasi. Meskipun Thread memiliki akses, tidak ada Thread lain yang dapat menggunakan sumber daya. Masalah yang saya hadapi sekarang adalah bahwa saya telah bergerak ke arah menerapkan sistem saya menggunakan pola async / menunggu, untuk memungkinkan implementasi sequencer bersih. Masalahnya adalah sekarang sequencer saya tidak selalu berjalan di thread yang sama; thread aktif dapat berubah selama callback, jadi tidak mudah untuk menentukan apakah saya dalam konteks yang valid untuk terus menjalankan operasi. Salah satu item catatan adalah bahwa beberapa Operasi itu sendiri terdiri dari menunggu, yang berarti kedua urutan dan Operasi individu dapat menjangkau beberapa utas.

Pertanyaan saya: apakah ada yang tahu pola yang baik untuk berurusan dengan memperoleh akses eksklusif di hadapan thread switching karena async / menunggu?

Untuk referensi, beberapa hal yang saya pertimbangkan:

  1. Saya bisa membuat SynchronizationContext kustom yang marsekal semua sequencer panggilan untuk durasi urutan kembali ke Thread tunggal. Ini bermanfaat untuk memungkinkan saya menggunakan kembali kode pengelolaan akses thread-afinitas yang ada. Kekurangannya adalah bahwa ini akan membutuhkan dedikasi Thread kapan pun saya melakukan Urutan atau Operasi (karena Operasi juga dapat menjangkau beberapa utas.)

  2. Buat token akses yang dapat diperoleh untuk lolos ke metode Operasi untuk membuktikan bahwa Anda telah memperoleh akses. Ini memiliki sisi buruk dari kembung metode dengan parameter token.

  3. Gunakan pendekatan token akses dari (2), tetapi buat implementasi antarmuka duplikat untuk antarmuka Operasi sehingga pembungkus dapat dipakai dengan token 'panggang-dalam'. Ini menciptakan kode lem jelek, tetapi membersihkan kode sequencer sehingga tidak perlu lagi memberikan token ke masing-masing metode.


32
2017-10-02 16:43


asal


Jawaban:


Pertanyaan saya: apakah ada yang tahu pola yang baik untuk berurusan dengan memperoleh akses eksklusif di hadapan thread switching karena async / menunggu?

Ya, Anda bisa menggunakannya AsyncLock, yang juga tersedia sebagai bagian dari saya Pustaka AsyncEx. Jika Anda ingin memiliki jenis operasi "TryLock", maka Anda mungkin harus membuat primitif Anda sendiri.

Anda kehilangan beberapa kemampuan untuk melakukan pemeriksaan keamanan: tidak ada cara untuk memeriksa apakah thread yang sedang dieksekusi memiliki spesifik AsyncLock.

Pilihan lainnya termasuk ConcurrentExclusiveSchedulerPair (yang saya blog tentang sini) atau TPL Dataflow.


22
2017-10-02 17:05



Ada SemaphoreSlim.WaitAsync yang sangat cocok di sini. (Saya menemukannya pertanyaan serupa).


10
2017-11-16 13:02