Saya mencoba mendapatkan dokumen dari objek InternetExplorer.

Saya mengalami masalah dengan kode saya terjebak dalam panggilan fungsi untuk jangka waktu yang sangat lama - berlangsung beberapa jam. Masalah ini hanya jarang terjadi. Saya telah melacak masalah kembali ke cara kode saya berinteraksi dengan InternetExplorer. Dalam upaya untuk mengesampingkan mengakses InternetExplorer.Document saya telah memasukkan kode itu ke dalam utas terpisah.

Namun, sekarang gagal 100% dari waktu. Saya telah memecahkan kode sebanyak mungkin di dalam utas untuk melacak masalah yang sebenarnya dan object objDoc = win.Document; di bawah ini. Debugger sampai ke baris itu tetapi tidak pernah melewatinya. Tanpa threading biasanya butuh milidetik untuk mengembalikan Dokumen, meskipun kadang-kadang detik. Dengan threading sekarang membutuhkan lebih dari 5 menit yaitu ketika saya memiliki kode yang melemparkan pengecualian di utas utama.

Adakah yang punya ide di mana masalahnya dengan kode berulir yang saya tulis?

private InternetExplorer window;
private object lockObject = new object();
private HTMLDocument childThreadDocument;
private Thread childThread;

public HTMLDocument GetDocument()
{
    DateTime start = DateTime.Now;
    childThread = new Thread(() => threadedGetDocument());
    childThread.Start();
    while (true)
    {
        if ((DateTime.Now - start).TotalMinutes > 5) throw new Exception();
        lock (lockObject)
        {
            if (childThreadDocument != null) return childThreadDocument;
        }
    }
}

private void threadedGetDocument()
{
    InternetExplorer win = window;
    object objDoc = win.Document;
    HTMLDocument doc = (HTMLDocument)objDoc;
    lock (lockObject)
    {
        childThreadDocument = doc;
    }
}
0
jonyfries 10 Juli 2020, 18:47

1 menjawab

Jawaban Terbaik

Saya akhirnya bisa menyelesaikan masalah ini. Seseorang yang memahami threading lebih baik daripada saya mungkin dapat menjelaskan alasannya. Namun saya kira mengganti utas ketika mencoba mengakses COM menyebabkannya hang - memaksa utas utama untuk menunggu utas anak selesai memperbaiki masalah.

public HTMLDocument GetDocument()
{
    DateTime start = DateTime.Now;
    childThread = new Thread(() => threadedGetDocument());
    childThread.Start();
    childThread.Join(new TimeSpan(0, 5, 0));
    lock (lockObject)
    {
        if (childThreadDocument != null)
            return childThreadDocument;
        else 
            throw new ExecutionEngineException("Failed to open IE Document");
    }
}

Perhatikan jika Anda membuat aplikasi yang perlu responsif, ini akan menjadi ide yang buruk jika diterapkan. Jika panggilan seperti ini dilakukan di utas GUI maka aplikasi tidak akan merespons input pengguna hingga lima menit. Namun, aplikasi saya adalah aplikasi konsol yang diam-diam bekerja di VM untuk memproses dan mendistribusikan pekerjaan yang masuk. Jeda singkat tidak menyebabkan kerusakan apa pun.

0
jonyfries 10 Juli 2020, 18:35