Di utas ini (diposting sekitar setahun yang lalu) ada diskusi tentang masalah yang bisa datang dengan menjalankan Word dalam sesi non-interaktif. Nasihat (cukup kuat) yang diberikan di sana adalah untuk tidak melakukannya. Dalam satu posting dinyatakan "Office API semua mengasumsikan Anda menjalankan Office dalam sesi interaktif di desktop, dengan monitor, keyboard dan mouse dan, yang paling penting, pompa pesan." Saya tidak yakin apa itu. (Saya telah memprogram di C # hanya sekitar satu tahun; pengalaman pemrograman saya yang lain terutama dengan ColdFusion.)
Memperbarui:
Program saya berjalan melalui sejumlah besar file RTF untuk mengekstrak dua bagian informasi yang digunakan untuk membuat nomor laporan medis. Daripada mencoba dan mencari tahu bagaimana instruksi pemformatan di RTF bekerja, saya memutuskan untuk membukanya di Word dan menarik teks keluar dari sana (tanpa benar-benar memulai GUI). Kadang-kadang, program tersendat di tengah pemrosesan satu file, dan meninggalkan utas Word terbuka yang melekat pada dokumen itu (saya masih harus mencari cara untuk menutupnya). Ketika saya menjalankan ulang program, tentu saja saya mendapat pemberitahuan bahwa ada utas yang menggunakan file itu, dan apakah saya ingin membuka salinan hanya-baca? Ketika saya berkata Ya, Word GUI tiba-tiba muncul entah dari mana dan mulai memproses file. Saya bertanya-tanya mengapa itu terjadi;
sumber
Jawaban:
Loop pesan adalah sepotong kecil kode yang ada di program Windows asli apa pun. Secara kasar terlihat seperti ini:
GetMessage () Win32 API mengambil pesan dari Windows. Program Anda biasanya menghabiskan 99,9% waktunya di sana, menunggu Windows mengatakan sesuatu yang menarik terjadi. TranslateMessage () adalah fungsi pembantu yang menerjemahkan pesan keyboard. DispatchMessage () memastikan bahwa prosedur jendela dipanggil dengan pesan tersebut.
Setiap program .NET berkemampuan GUI memiliki loop pesan, itu dimulai oleh Application.Run ().
Relevansi loop pesan ke Office terkait dengan COM. Program Office adalah program yang mendukung COM, begitulah cara kerja kelas Microsoft.Office.Interop. COM menangani threading atas nama coclass COM, ini memastikan bahwa panggilan yang dibuat pada antarmuka COM selalu dibuat dari utas yang benar. Sebagian besar kelas COM memiliki kunci registri di registri yang menyatakan ThreadingModel mereka, sejauh ini yang paling umum (termasuk Office) menggunakan "Apartemen". Artinya, satu-satunya cara yang aman untuk memanggil metode antarmuka adalah dengan melakukan panggilan dari thread yang sama yang membuat objek kelas. Atau dengan kata lain: sejauh ini sebagian besar kelas COM tidak aman untuk thread.
Setiap utas yang diaktifkan COM milik apartemen COM. Ada dua macam, Apartemen Single Threaded (STA) dan Apartemen Multi Thread (MTA). Kelas COM berulir apartemen harus dibuat pada utas STA. Anda dapat melihat ini kembali di program .NET, titik masuk utas UI dari program Windows Forms atau WPF memiliki atribut [STAThread]. Model apartemen untuk utas lainnya disetel dengan metode Thread.SetApartmentState ().
Sebagian besar pipa Windows tidak akan berfungsi dengan benar jika utas UI bukan STA. Terutama Drag + Drop, clipboard, dialog Windows seperti OpenFileDialog, kontrol seperti WebBrowser, aplikasi Otomasi UI seperti pembaca layar. Dan banyak server COM, seperti Office.
Persyaratan sulit untuk thread STA adalah thread tersebut tidak boleh memblokir dan harus memompa loop pesan. Loop pesan penting karena itulah yang digunakan COM untuk mengatur panggilan metode antarmuka dari satu utas ke utas lainnya. Meskipun .NET membuat panggilan marshaling menjadi mudah (Control.BeginInvoke atau Dispatcher.BeginInvoke misalnya), sebenarnya ini adalah hal yang sangat rumit untuk dilakukan. Utas yang menjalankan panggilan harus dalam keadaan terkenal. Anda tidak bisa secara sewenang-wenang menyela utas dan memaksanya melakukan panggilan metode, yang akan menyebabkan masalah masuk kembali yang mengerikan. Sebuah utas harus "diam", tidak sibuk menjalankan kode apa pun yang mengubah status program.
Mungkin Anda bisa melihat ke mana arahnya: ya, ketika sebuah program menjalankan loop pesan, program itu menganggur. Penyusunan sebenarnya terjadi melalui jendela tersembunyi yang dibuat COM, ia menggunakan PostMessage agar prosedur jendela dari jendela itu mengeksekusi kode. Di utas STA. Loop pesan memastikan bahwa kode ini berjalan.
sumber
"Pompa pesan" adalah bagian inti dari setiap program Windows yang bertanggung jawab untuk mengirimkan pesan windowing ke berbagai bagian aplikasi. Ini adalah inti dari pemrograman Win32 UI. Karena keberadaannya di mana-mana, banyak aplikasi menggunakan pompa pesan untuk meneruskan pesan di antara modul yang berbeda, itulah sebabnya aplikasi Office akan rusak jika dijalankan tanpa UI apa pun.
Wikipedia memiliki deskripsi dasar .
sumber
John berbicara tentang bagaimana sistem Windows (dan sistem berbasis jendela lainnya - X Window , Mac OS asli ....) mengimplementasikan antarmuka pengguna asinkron menggunakan peristiwa melalui sistem pesan.
Di balik layar untuk setiap aplikasi terdapat sistem pesan di mana setiap jendela dapat mengirim acara ke jendela lain atau pendengar acara - ini diimplementasikan dengan menambahkan pesan ke antrian pesan. Ada loop utama yang selalu berjalan melihat antrian pesan ini dan kemudian mengirimkan pesan (atau peristiwa) ke pendengar.
Artikel Wikipedia Message loop di Microsoft Windows menunjukkan contoh kode program Windows dasar - dan seperti yang Anda lihat di tingkat paling dasar, program Windows hanyalah "pompa pesan".
Jadi, untuk menyatukan semuanya. Alasan program windows yang dirancang untuk mendukung UI tidak dapat bertindak sebagai layanan adalah karena program ini membutuhkan loop pesan yang berjalan sepanjang waktu untuk mengaktifkan dukungan UI. Jika Anda menerapkannya sebagai layanan seperti yang dijelaskan, ini tidak akan dapat memproses penanganan peristiwa asinkron internal.
sumber
Dalam COM , pompa pesan akan melakukan serialisasi dan menonaktifkan pesan yang dikirim antar apartemen. Apartemen adalah proses mini di mana komponen COM dapat dijalankan. Apartemen hadir dalam mode ulir tunggal dan ulir gratis. Apartemen single threaded terutama merupakan sistem warisan untuk aplikasi komponen COM yang tidak mendukung multi-threading. Mereka biasanya digunakan dengan Visual BASIC (karena ini tidak mendukung kode multi-utas) dan aplikasi warisan.
Saya kira bahwa persyaratan pompa pesan untuk Word berasal dari COM API atau bagian dari aplikasi yang tidak aman untuk thread. Ingatlah bahwa model penguliran dan pengumpulan sampah .NET tidak berfungsi baik dengan COM di luar kotak. COM memiliki mekanisme pengumpulan sampah dan model penguliran yang sangat sederhana yang mengharuskan Anda melakukan berbagai hal dengan cara COM. Menggunakan PIA Office standar masih mengharuskan Anda untuk secara eksplisit menutup referensi objek COM, jadi Anda perlu melacak setiap pegangan COM yang dibuat. PIA juga akan membuat barang di belakang layar jika Anda tidak berhati-hati.
Integrasi .NET-COM adalah keseluruhan topik dengan sendirinya, dan bahkan ada buku yang ditulis tentang subjek tersebut. Bahkan menggunakan COM API untuk Office dari aplikasi desktop interaktif mengharuskan Anda untuk melewati rintangan dan memastikan bahwa referensi dirilis secara eksplisit.
Office dapat dianggap tidak aman untuk utas, jadi Anda memerlukan contoh Word, Excel , atau aplikasi Office lain yang terpisah untuk setiap utas. Anda harus menanggung overhead awal atau mempertahankan kumpulan utas. Kumpulan utas harus diuji dengan cermat untuk memastikan semua referensi COM dirilis dengan benar. Bahkan memulai dan mematikan instans mengharuskan Anda untuk memastikan semua referensi dirilis dengan benar. Kegagalan menandai i dan melewati t Anda di sini akan mengakibatkan sejumlah besar objek COM yang mati dan bahkan seluruh contoh Word yang sedang berjalan bocor.
sumber
Wikipedia menyarankan itu berarti Event Loop utama program .
sumber
Menurut saya diskusi Channel 9 ini memiliki penjelasan singkat yang bagus:
sumber