许多线程,一个方法失败

本文关键字:一个 方法 失败 多线程 | 更新日期: 2023-09-27 18:10:34

我的应用程序是系统托盘应用程序,使用c#, . net 4.0。

我试图一次显示许多PDF文件,每个PDF应该与其他窗口分割屏幕,我通过ProcessName确定,这就是全部。

困难在于我需要等到用户关闭该窗口(. waitforexit()方法),因为稍后我要删除PDF文件。问题来了。

在第一个线程一切都很好,但问题是当我试图显示第二个PDF文件窗口processList[0]虽然MoveWindow函数返回true,并且处理该窗口也是正确的,只有PDF窗口正在调整大小,其他窗口失败。

在main方法中,我创建的唯一线程(每次用户想要查看pdf文件时,我都会调用这段代码几次):

Thread pdfThread = new Thread(() => ShowPdfFile(fullPath));
pdfThread.Start();

Then(简化代码)

public static void ShowPdfFile(string fileName)
        {
            try
            {
                 Process pdfProcess = Process.Start(fileName);
                 Thread.Sleep(500);
                 string windowTitle = GetActiveWindowTitle();
                 IntPtr pdfHandle = (IntPtr)FindWindow(null, windowTitle);
                 MoveWindow(pdfHandle, 0, 0, 0, 0, true);
                 Process[] processList = Process.GetProcessesByName("someProcess");
                 MoveWindow(processList[0].MainWindowHandle, 0, 0, 0, 0, true);
                 pdfProcess.WaitForExit();
                 MoveWindow(processList[0].MainWindowHandle, 0, 0, max, max, true);
            }
            catch (Exception ex)
            {
                LogToFile(ex);
            }
            finally
            {
                try
                {
                    File.Delete(fileName);
                }
                catch
                {
                    LogToFile("Cannot delete file");
                }
            }

UPDATE:嗯,我一整天都在调试它,但刚才我注意到,在第二个线程上,它不在线等待pdfProcess.WaitForExit();我应该做些什么来强制线程等待确切的pdfProcess退出?

许多线程,一个方法失败

你的用法有一个基本问题:为每个文件启动外部PDF应用程序。但是,这并不能确保您有多个进程。

例如Acrobat reader只启动一个进程。其他文件只会作为新窗口"添加"到第一个进程中(你可以通过尝试手动打开Acrobat reader两次来检查这一点——>不起作用)。

所以简而言之:如果你不能控制使用哪个PDF阅读器(并且可以确保每个文件都有一个单独的处理过程),你的方法将不起作用。

注意:理论上可以等到用户关闭包含特定文件的"阅读器窗口"。但是我强烈建议不要这样做:

  1. 在不同的进程中查找窗口是非常容易出错的(除非该进程明确地以这种方式设计…)
  2. 解决方案将再次依赖于阅读器应用程序(您不能确定Acrobat和Nitro使用类似的架构来命名两个阅读器)

基本上,如果这个特性非常重要,您应该考虑购买一个PDF查看器组件,它允许将PDF作为您自己进程的窗口显示。

编辑第二个线程没有等待的原因是将文件"添加"到第一个进程的功能使用了一个临时进程:

  1. 为新文件启动临时进程
  2. 临时进程检查应用程序是否已经在运行
  3. 临时进程通知第一个进程打开特定文件
  4. 临时进程关闭。

因此等待该进程将几乎立即返回,因为所讨论的进程已经停止(或将在几毫秒内停止)。

Daniel是对的,但是我找到了一个解决方案!在这里,也许有人会用它。
小提示:我们必须使用winapi解决方案,而不是。waitforexit()。
最重要的部分是while循环,它等待关闭pdf窗口。
记住FindWindow()和IsWindow()方法来自user32.dll (winapi)。
这段代码基于进程的路径运行进程,然后获取它的句柄并等待它的闭包。

Process pdfProcess = new Process();
pdfProcess.StartInfo.FileName = filePath;
if (pdfProcess.Start())
{
    Thread.Sleep(500);
    Process[] processlist = Process.GetProcesses();
    string windowTitle = string.Empty;
    foreach (Process process in processlist)
    {
        if (!String.IsNullOrEmpty(process.MainWindowTitle) && process.MainWindowTitle.Contains(fileName))
        {
            windowTitle = process.MainWindowTitle;
        }
    }
    IntPtr pdfHandle = FindWindow(null, windowTitle);
    while (IsWindow(pdfHandle) && userExitedApp == false)
        Thread.Sleep(100);
}

多个线程可以一个接一个地使用一个方法。也许这个视频会有所帮助https://www.youtube.com/watch?v=XhGXh9Z5GTw&特性= em-upload_owner