[英]C# print file, wait for close file - program hang up
我编写了在目录(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;
}
}
您正在通过Dispatcher.Invoke
执行while (!IsFileReady(info)) { }
,这将在UI线程上执行代码,因此它将肯定会阻止该应用程序。
您根本没有与UI进行交互,因此正确的方法是通过Task
, await
或通过ThreadPool
与后台线程异步执行它,而根本不使用Dispatcher.Invoke
。
通过启动新任务,尝试在后台线程上的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");
}
}
使用BackgroundWorker代替Dispatcher.Invoke。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.