Friday 4 August 2017

Outputdatareceived Waitforexit


NET System. Diagnostics. Process Class 8211 Bagian 1 Proses. WaitForExit dan. Exited event aren8217t working Saya pikir saya telah menemukan ini sebagai kasus tapi itu salah saya, mungkin sama untuk Anda juga. Saya akan membahas apa yang saya temukan sambil menjelajahi dan memecahkan masalah ini. Jawaban singkat: Jika Anda mengarahkan StandardOutput dan StandardError, gunakan metode asynchronous Process. BeginErrorReadLine () dan. BeginOutputReadLine () yang tepat sebelum memanggil. WaitForExit () dan jadikan hasilnya dengan mengaitkan peristiwa Process. ErrorDataReceived dan. OputputDataReceived. Jawaban panjang dimulai dengan saya menggunakan differnge. exe Visual Studio di folder Common7IDE untuk membandingkan file teks dalam mode batch. Saya memperkenalkan tes regresi ke dalam proses batch yang dimulai. Saya membutuhkan alat yang akan mengeluarkan file perbedaan teks saat membandingkan dua file (bukan file hasil gabungan). WinMerge dan Beyond Compare ada di tangan saya tapi sepertinya tidak menghasilkan apapun kecuali hasil gabungan (yang biasanya adalah apa yang saya inginkan, tapi kali ini tidak). Kerangka regresi saya akan memanggil diffmerge. exe dan menyimpan file diff yang dihasilkan untuk ditinjau nanti. Saya mengkodekan ProcessStartInfo saya Mengikuti hal itu dengan menendang proses dan menunggu proses berakhir. Dan tunggu tunggu tunggu. Ini membuat saya membaca MSDN dan menggali lebih dalam penggunaan kelas Proses. Saya menemukan beberapa informasi menarik, mungkin seharusnya sudah jelas. Pertama, saya menemukan bahwa terkadang menjalankan Proses Anak saya yang berbeda dengan argumen yang berbeda, terkadang tidak membuat masalah misterius. Kedua, saya menemukan bahwa itu bekerja dengan baik ketika saya tidak mengarahkan output. Jadi, jelas aku melewatkan sesuatu. Saya perlu benar-benar membaca dokumentasi API Proses, dan dengan demikian saya menemukan nugget ini: Artikel MSDN Setelah menemukan dan membaca artikel MSDN yang saya mengerti. Sampel kode saya di atas akan bekerja jika buffer StdOut atau StdError tidak terisi. Namun apa yang saya lihat adalah buffer StdOut yang terisi, Proses Anak diblokir pada tulisan StdOutStdError berikutnya, Proses Orangtua menunggu jauh di Proses Anak untuk keluar sebelum membaca dari buffer StdOutStdError. Bagi saya sepertinya metode WaitForExit dan dan acara Exceed yang rusak tidak menangkap proses child yang keluar, namun itu adalah kode saya yang rusak. Saya memodifikasi kode untuk menggunakan metode asinkron dan tiba-tiba masalah saya hilang. Tidak ada lagi pemblokiran, semuanya berjalan seperti yang diharapkan. Saya menggunakan StringBuilder sebagai buffer untuk menampung data yang diterima dalam acara. Pada bagian 2, saya mengalami masalah dengan implementasi Proses StdOutStdError ReadLine seputar kebutuhan spesifik saya, saya membahas bagaimana saya menyelesaikan masalah itu. System. Diagnostics. Process Class Bagian 2 Pada Bagian 1 saya membahas masalah di mana menggunakan pengalihan stdoutstderr dan membacanya secara serentak, buffer output dapat menjadi penuh dan menghalangi proses anak pada penulisan selanjutnya. Kemudian kebuntuan terjadi karena proses induk menunggu anak untuk keluar sebelum membaca data dari buffer, anak tersebut memblok pada write karena buffer sudah penuh, sehingga kebuntuan. Jawabannya adalah sederhana 8211 yang terbaik untuk menggunakan metode asynchronous untuk membaca data dari stdoutstderr. Masalah ini bisa diduga dan saya buruk. Itu bukan AKU, ANDA. Saya mengalami masalah lain, yang tampak seperti kebuntuan yang sama, satu di mana asumsi buruk dalam penerapan kelas Microsofts Process menyebabkan jenis kebuntuan yang berbeda antara proses orang tua dan anak. Saya menemukannya ketika proses anak saya mendorong saya untuk menegaskan aktivitas yang diminta, lihat Gambar 1 untuk sebuah contoh. Perintah itu diakhiri tanpa baris baru, membiarkan kursor berada di akhir prompt (yang masuk akal, mengapa kursor berada di bawah perintah dan tidak di sampingnya di layar). Lihat Gambar 2 untuk contoh kode prompt ini. Proses Orangtua saya diberi kode untuk memeriksa data stdout yang diterima secara asinkron, mencari promptnya. Jika saat diminta diterima, proses orang tua akan memancarkan respons terhadap proses anak stdin. Lihat Gambar 3. Namun ketika saya menjalankan proses orang tua dan proses anak mengirimkan prompt, teks tersebut tidak pernah muncul dalam acara OutputDataReceived dan proses orang tua saya berada di jalur p. WaitForExit () selamanya Proses Anak sedang menunggu jawaban yang mana Tidak pernah datang dari orang tua, dan kami sekali lagi dalam kebuntuan, kali ini aku bukan saya. Masalahnya bukan kode saya. Tidak ada NewLine, tidak ada DataReceivedEvent Saya mulai melakukan debugging dan menonton acara OutputDataReceived dan mulai mengubah kode proses anak dengan berbagai cara. Perubahan kecil di bawah menyebabkan acara OutputDataReceived menyala dengan teks prompt, lihat Gambar 4. Dari beberapa tes lainnya, sepertinya peristiwa OutputDataReceived hanya akan terjadi bila NewLine ada dalam keluaran dari proses anak. Sebuah prompt tanpa NewLine tidak akan memecat acara OutputDataReceived dan dengan demikian proses induk tidak mendapatkan prompt dan tidak dapat merespons. Deadlock Menerapkan pembacaan asynchronous saya sendiri tentang stdoutstderr Saya perlu membaca petunjuk dari proses anak yang sesuai dengan kode saya tapi aplikasi konsol pihak ke-3, jadi akhirnya saya harus bisa menerima perintah pada NewLines. Memecahkan masalah ini mengharuskan saya untuk menerapkan kelas Async IO saya sendiri untuk membaca proses stdoutstderror. Saya membuat sebuah kelas bernama StdStreamReader yang membaca sebuah acara streaming dan kebakaran yang pada dasarnya serupa dengan event Process OutputDataReceived, namun tidak mematikan NewLine untuk memecat data yang diterima namun malah menyala begitu data diterima. Pada Gambar 5 saya telah menyoroti perbedaan kode dalam kode proses Orang Tua dengan menggunakan kelas pembaca baru. Kode untuk StdStreamReader cukup biasa, tapi hasilnya seperti yang diharapkan, lihat Gambar 6. Perhatikan bahwa Ya tidak ditampilkan tepat setelah prompt ini karena dikirim langsung ke proses anak stdin dan tidak ditampilkan. Klik untuk Full Source Code. Yang disediakan secara dasar, tanpa jaminan apapun.

No comments:

Post a Comment