C#打印文件,等待关闭文件 - 程序挂起

时间:2017-01-27 14:20:12

标签: c# wpf printing

我编写了一个监听目录(GUI - WPF)的程序。当此目录中显示的新文件发送到打印机时。当我尝试将大文件保存到此目录时,会发生此问题。我必须等到文件关闭,然后将其发送到打印机。我有一个函数来检查文件是否打开。但是当我在整个GUI挂起时使用它。如何异步使用此功能?

 protected void newfile(object fscreated, FileSystemEventArgs Eventocc)
        {
            try
            {
                    string CreatedFileName = Eventocc.Name;
                    FileInfo createdFile = new FileInfo(CreatedFileName);
                    string extension = createdFile.Extension;
                    string eventoccured = Eventocc.ChangeType.ToString();
                    fsLastRaised = DateTime.Now;

                        this.Dispatcher.Invoke((Action)(() =>
                        {
                            String file = "";
                            file = watchingFolder + "\\" + CreatedFileName;                                  
                            //printing
                            this.Dispatcher.Invoke((Action)(() =>
                            {
                                FileInfo info = new FileInfo(file);
                                while (!IsFileReady(info)) { }
                                var t = new Thread(() => printFile(file, extension)); //send to printer
                                t.Start();
                            }));

                        }));
                    }

            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show("Error");
            }
        }

IsFileReady功能:

 public static bool IsFileReady(FileInfo file)
        {
            FileStream stream = null;

            try
            {
                stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
            }
            catch (IOException)
            {
                //the file is unavailable because it is:
                //still being written to
                //or being processed by another thread
                //or does not exist (has already been processed)
                return true;
            }
            finally
            {
                if (stream != null)
                    stream.Close();
            }
            //file is not locked
            return false;
        }

printfile

 public void printFile(string filepath, string ext)
        {
                    ProcessStartInfo info = new ProcessStartInfo();
                    info.Verb = "print";
                    info.FileName = filepath;
                    info.CreateNoWindow = true;
                    info.WindowStyle = ProcessWindowStyle.Hidden;

                    Process p = new Process();
                    p.StartInfo = info;
                    p.Start();

                    p.WaitForInputIdle();
                    System.Threading.Thread.Sleep(3000);

                    if (false == p.CloseMainWindow())
                        p.Kill();

                }
        }

如何更正此代码以使用大文件而不会挂起?

编辑:

要检查新文件,请使用FileSystemWatcher

private void start(object sender, RoutedEventArgs e)
        {


            if (watchingFolder == null)
            {

            }
            else
            {
                fs = new FileSystemWatcher(watchingFolder, "*.*");
                fs.EnableRaisingEvents = true;
                fs.IncludeSubdirectories = true;
                fs.Created += new FileSystemEventHandler(newfile);
                btnSatrt.IsEnabled = false;
                btnStop.IsEnabled = true;

            }
        }

3 个答案:

答案 0 :(得分:1)

您正在执行while (!IsFileReady(info)) { }Dispatcher.Invoke,执行UI线程上的代码,因此它会阻止确定应用。

您根本不与UI进行交互,因此正确的方法是通过Taskawait或通过后台线程{{1}异步执行它并且根本不使用ThreadPool

答案 1 :(得分:0)

尝试通过启动新任务在后台线程上的newfile事件处理程序中执行所有代码:

protected async void newfile(object fscreated, FileSystemEventArgs Eventocc)
{
    try
    {
        await Task.Run(() =>
        {
            string CreatedFileName = Eventocc.Name;
            FileInfo createdFile = new FileInfo(CreatedFileName);
            string extension = createdFile.Extension;
            string eventoccured = Eventocc.ChangeType.ToString();
            fsLastRaised = DateTime.Now;

            string file = watchingFolder + "\\" + CreatedFileName;
            FileInfo info = new FileInfo(file);
            while (!IsFileReady(info)) { }
            printFile(file, extension);
        });
    }
    catch (Exception ex)
    {
        System.Windows.Forms.MessageBox.Show("Error");
    }
}

答案 2 :(得分:0)

使用BackgroundWorker代替Dispatcher.Invoke。