简体   繁体   中英

C# print file, wait for close file - program hang up

I wrote program that listens on a directory (GUI - WPF). When the new file show up in this directory is sent to the printer. The problem occurs when I try to save a large file to this directory. I have to wait until the file is closed, and then send it to the printer. I have a function that checks if the file is open. But when I use it in the whole GUI hangs. How do I use this function asynchronously?

 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 function:

 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;
        }

And 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();

                }
        }

How can I correct this code to work with large files without hangs up?

EDIT:

For check new file I use 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;

            }
        }

You're executing while (!IsFileReady(info)) { } through Dispatcher.Invoke , that executes the code on the UI thread so it will block for sure the app.

You aren't interacting at all with the UI, so the correct approach is to execute it asynchronously, via Task s and await s or with a background thread via the ThreadPool and not using at all Dispatcher.Invoke .

Try to execute all code in the newfile event handler on a background thread by starting a new task:

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");
    }
}

使用BackgroundWorker代替Dispatcher.Invoke。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM