Вопрос

Хорошо, вот сделка ...

У меня есть программа Windows (XP) в .net 2.0 (C#), которая позволяет пользователям переименовать заданный файл .pdf. (Имя файла является «структурно описательным», поскольку оно излагает простую информацию о том, что в самом файле.) В единственной форме программы есть объект Linklabel, который позволяет пользователю открывать сам .pdf, чтобы они могли видеть что они переименовывают.

Хитрость заключается в том, что когда пользователь вносит соответствующие изменения (ы) и нажимает кнопку «Сохранить», я хочу, чтобы окно акробата, показывающее .pdf закрыть, выполняется сохранение, файл «следующий», чтобы быть полученным, и новое окно немедленно Откройте отображение этого следующего файла.

Вот соответствующие фрагменты кода:

    private void OpenViewer()
    {
        // NOTE: pdfView is of type Process, in case you're not familiar with
        // Process.Start().
        pdfView = System.Diagnostics.Process.Start(lnkFile.Links[0].LinkData.ToString());
    }

    private bool KillViewer()
    {
        bool result = (pdfView != null);

        if (pdfView != null)
        {
            pdfView.CloseMainWindow();
            pdfView.Close();
            pdfView.Dispose();
            pdfView = null;
            GC.Collect();

            // Verify that the lock is available before you return, as returning basically says:
            // "Yup, the file's available."
            bool locked = false;
            StreamWriter sw = null;
            do
            {
                try
                {
                    sw = new StreamWriter(new FileStream(lnkFile.Links[0].LinkData.ToString(), FileMode.Open));
                    locked = false;
                }
                catch (Exception)
                {
                    locked = true;
                }
            } while (locked);

            sw.Dispose();
        }

        return result;
    }

    private void SomeButtonEvent
    {
        // Record whether a viewer was open in the first place.
        bool viewerActive = KillViewer(); 

        PerformFileLockingMethod();
        GetNextFile()

        if(viewerActive)
        {
            OpenViewer();
        }
    }

Обратите внимание на Killviewer (), что в основном есть цикл с захватом блокировки, чтобы убедиться, что программа не пытается переименовать рабочий файл до тех пор, пока просмотрщик PDF полностью не выпустил блокировку.

Проблема заключается в следующем: иногда все работает прекрасно, а иногда Killviewer разрывается на вызове CloseMainWindow () с InvalidoperationException, Details = «Процесс вышел, поэтому запрошенная информация недоступна». Это было бы довольно просто, если бы не две вещи ...

1: pdfview.hasexited = true

А ТАКЖЕ

2: Проклятый PDF -зритель все еще открыт !!!

Как это возможно? Есть ли команда процесса, которую я должен использовать для обеспечения закрытия окна? К вашему сведению, программа ссылается на то, что ничто не за пределами системы.* Пространства имен или внутренне созданный класс, который также в конечном итоге ссылается только на систему.*.

Спасибо.

Это было полезно?

Решение 2

После дальнейшего расследования я думаю, что определил, что происходит.

Я не детализировал детали рабочего процесса, потому что я не мог надежно повторить ситуацию. После дальнейших попыток я нашел две надежные ситуации ...

  1. Нажмите на ссылку несколько раз, а затем нажмите «Сохранить».
  2. Нажмите на ссылку, закройте окно просмотра и нажмите «Сохранить».

В каждом из этих случаев проблема сводилась к процессу, на который PDFViewer не синхронизировался с тем, что делал пользователь.

  1. Если ссылка нажимала несколько раз, то активный просмотрщик был на процессе, не связанном с процессом PDFViewer, следовательно, казалось бы, невозможной ситуации, подробно описанной выше.

  2. Если ссылка была нажата, а окно было закрыто, переменная PDFViewer останется, оставив процесс с hasexited = true.

Урок «Возьми домой всего этого»: если вы запускаете отдельный процесс от своего основного пользовательского интерфейса, убедитесь, что вы охватываете каждую возможную ситуацию, которая может произойти с внешним процессом.

Для протокола Ник Геррера заслуживает очков за то, что он направил меня к идентификаторам процесса. Это в конечном итоге решило это.

Другие советы

Попробуйте вместо этого ..

pdfView.Kill();
pdfView.WaitForExit();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top