繁体   English   中英

使用后台工作者的 UI 无响应,处理文件非常慢

[英]Unresponsive UI using background worker, processing files are very slow

使用后台工作者的 UI 无响应,处理文件非常慢。 这里遇到了两个不同的问题。 GDpicture SDK 用于图像处理。 CPU 利用率最低,我怎样才能最大限度地提高性能,最终拥有响应迅速且快速的 wpf 应用程序。

命名空间 OCR { 公共部分类 MainWindow : Window

{
    BackgroundWorker bw;/*= new BackgroundWorker();*/
    private SynchronizationContext threadSyn = null;

   string log_cap = string.Empty;
    List<string> log_list = new List<string>();
    

    string value = "Merged";

    public MainWindow()
    {
        try
        {
            InitializeComponent();
            InitializeBackgroundWorker();
            File_process();
            string configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"path.txt");
            string[] configfile = File.ReadAllLines(configpath);
            if (configfile.Length > 1)
            {
                ip.Text = configfile[0];
                op.Text = configfile[1];
                ex_tb.Text = configfile[2];
                Protb.Text = configfile[3];
            }               
            cbPDFConform.Items.Clear();
            for (int i = 0; i < Enum.GetNames(typeof(PdfConformance)).Length - 1; i++)
            {
                ComboBoxItem cbi = new ComboBoxItem();
                cbi.Content = Enum.GetName(typeof(PdfConformance), (PdfConformance)i);
                PdfConformance test = (PdfConformance)i;
                cbi.Tag = (PdfConformance)i;
                cbPDFConform.Items.Add(cbi);
            }
            cbPDFConform.SelectedIndex = 0;
            cbProcessorCount.Items.Clear();
            for (int i = 1; i <= Environment.ProcessorCount; i++)
            {
                cbProcessorCount.Items.Add(i.ToString());
                if (Environment.ProcessorCount / 2 == i) { cbProcessorCount.SelectedIndex = i - 1; }
            }
            LicenseManager oLicenseManager = new LicenseManager();
            oLicenseManager.RegisterKEY("");

            configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"path.txt");
            configfile = File.ReadAllLines(configpath);
            if (configfile.Length > 1)
            {
                ip.Text = configfile[0];
                op.Text = configfile[1];
                ex_tb.Text = configfile[2];
                Protb.Text = configfile[3];
            }
            GrantAccess(ip.Text);
            GrantAccess(op.Text);
            GrantAccess(ex_tb.Text);
            GrantAccess(Protb.Text);
            threadSyn = SynchronizationContext.Current;
        }

        catch (Exception e1)
        { MessageBox.Show("e1" + e1.Message); }
    }

    private void InitializeBackgroundWorker()
    {
        bw = new BackgroundWorker();
        bw.DoWork += Bw_DoWork;
        bw.WorkerSupportsCancellation = true;           

    }             

    public async void File_process()
    {           
     await Task.Run(() => converttiffpdfreducer());               
    }

    private void Bw_DoWork(object sender, DoWorkEventArgs e)
    {
        this.Dispatcher.Invoke(() =>
        {               
            try
            {
                using (StreamWriter sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"path.txt"), false))
                {
                    sw.WriteLine(ip.Text);
                    sw.WriteLine(op.Text);
                    sw.WriteLine(ex_tb.Text);
                    sw.WriteLine(Protb.Text);
                    sw.Close();
                }
                ParallelOptions parallelOptions = new ParallelOptions();
                parallelOptions.MaxDegreeOfParallelism = int.Parse(cbProcessorCount.SelectedItem.ToString());
                var watch1 = new System.Diagnostics.Stopwatch();
                watch1.Start();
                converttiffpdfreducer();
                //deletenew();
                watch1.Stop();
                TimeSpan ts1 = watch1.Elapsed;
                ts1.ToString("mm\\:ss");

                if (MergeChk.IsChecked == false)
                {
                    value = "OCRed";
                }
                WriteLn("All documents have been successfully " + value + " " + ts1 + " " + DateTime.Now +" "+Environment.UserName);                    
            }
            catch (Exception DOwork)
            { MessageBox.Show("e2 " + DOwork.Message); }
        });
    }
    private void GrantAccess(string fullPath)
    {
        DirectoryInfo dInfo = new DirectoryInfo(fullPath);
        DirectorySecurity dSecurity = dInfo.GetAccessControl();
        dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
        dInfo.SetAccessControl(dSecurity);
    }
    private string[] mutliocr(string[] arr)
    {
        string box = string.Empty;
        string box1 = string.Empty;
        try
        {
            string filepath = string.Empty;
            string outpath = ex_tb.Text;
            if (MergeChk.IsChecked == true)
            { filepath = op.Text; }
            else if (MergeChk.IsChecked == false)
            { filepath = Protb.Text; }
            System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
            {
                Thread.CurrentThread.IsBackground = true;
            var watch2 = new System.Diagnostics.Stopwatch();
            watch2.Start();
            string[] getfilearray = arr;
            for (int f = 0; f < getfilearray.Length; f++)
            {
                string dirName = Directory.GetParent(getfilearray[f]).FullName;
                string folder = Directory.GetParent(getfilearray[f]).FullName;

                box = Path.GetDirectoryName(getfilearray[f]);
                box1 = Path.GetDirectoryName(box);
                string getextension = Path.GetExtension(getfilearray[f]);
                string[] newF = Directory.EnumerateFiles(dirName, "*.*", SearchOption.AllDirectories).ToArray();
                string FN = Directory.GetParent(getfilearray[f]).Name;
                string ocrfolder = (new FileInfo(getfilearray[f]).Directory.FullName);
                string filen = Path.Combine(ocrfolder, folder, FN + "-ocr" + getextension);
                string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
                if (!Directory.Exists(ocrfolder))
                {
                    Directory.CreateDirectory(ocrfolder);
                }
                GrantAccess(ocrfolder);
                GdPicturePDF oGdPicturePDF = new GdPicturePDF();
                oGdPicturePDF.OcrPagesDone += OcrPagesDone;
                void OcrPagesDone(GdPictureStatus status1)
                {
                    if (oGdPicturePDF.SaveToFile(filen) == GdPictureStatus.OK)
                    { }
                    else
                        MessageBox.Show("PDF: The OCR-ed file has failed to save. Status: " + oGdPicturePDF.GetStat().ToString());
                }
                GdPictureStatus status = GdPictureStatus.OK;
                    if (oGdPicturePDF.LoadFromFile(getfilearray[f], false) == GdPictureStatus.OK)
                        if (status == GdPictureStatus.OK)
                        {
                            if (oGdPicturePDF.OcrPages_4("*", 0, "eng", dict, "", 300, OCRMode.FavorSpeed, 1, true) == GdPictureStatus.OK)
                                if (status == GdPictureStatus.OK)
                                { }
                                else
                                { MessageBox.Show("PDF: The OCR process has failed. Status: " + status.ToString()); }
                        }
                        else
                        { MessageBox.Show("PDF: The PDF file has failed to load. Status: " + status.ToString()); }
                    
                oGdPicturePDF.Dispose();
                GrantAccess(getfilearray[f]);
                File.Delete(getfilearray[f]);
                watch2.Stop();
                TimeSpan ts2 = watch2.Elapsed;
                ts2.ToString("mm\\:ss");                    
                    WriteLn(" OCR pages " + filen.Replace(op.Text, "") + " " + ts2 + " " + DateTime.Now);                        
                }               
            if (MergeChk.IsChecked == true)
            {
                foreach (string str in Directory.EnumerateFiles(op.Text, "*.pdf", SearchOption.AllDirectories).ToArray())
                {
                    if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
                        File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
                }
            }
            if (MergeChk.IsChecked == false)
            {
                FileSystem.MoveDirectory(Protb.Text, op.Text, UIOption.AllDialogs);
                Directory.CreateDirectory(Protb.Text);
                string FF = string.Empty;
                foreach (string str in Directory.EnumerateFiles(op.Text, "*.pdf", SearchOption.AllDirectories))
                {

                    if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
                        File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
                }
            }

            }));
        }
        catch (Exception mul)
        {              
        }
        return arr;
    }

    public static string browseFolder()
    {
        Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
        System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
        System.Windows.Forms.DialogResult result = fbd.ShowDialog();
        string path = string.Empty;
        if (result == (System.Windows.Forms.DialogResult)MessageBoxResult.OK)
        {
            path = fbd.SelectedPath;

            if (path[path.Length - 1] != '\\')
            {
                path = path + "\\";
            }
        }
        return path;
    }

    private string[] converttiffpdfreducer()
    {
        string[] dir = null;
        string box = string.Empty;
        string box1 = string.Empty;
        string[] gg = null;
        try
        {
            string filepath = ip.Text;
            string outpath = Protb.Text;

            System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
            {
                PdfConformance optPDFConform = PdfConformance.Unknown;
                dir = Directory.EnumerateDirectories(filepath, "*.*", SearchOption.AllDirectories).Where(l => l.Length != 0).OrderBy(f => f).ToArray();
                for (int ad = 0; ad < dir.Length; ad++)
                {   string[] getfilearray = Directory.EnumerateFiles(dir[ad], "*.*", SearchOption.AllDirectories).ToArray();
                    if (getfilearray.Length == 0)
                        break;
                    if (getfilearray.Length != 0)
                        for (int f = 0; f < getfilearray.Length; f++)
                        {
                            string getext = Path.GetExtension(getfilearray[f]);
                            string fd = Path.GetDirectoryName(getfilearray[f]);
                            string op_path = fd.Replace(filepath, Protb.Text);
                            string getextension = Path.GetExtension(getfilearray[f]);
                            string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
                            string outputPath = fd.Replace(filepath, outpath);
                            string FNAME = Path.GetFileNameWithoutExtension(getfilearray[f]);
                            string fn = Path.GetDirectoryName(getfilearray[f]).Replace(filepath, outpath);
                            string filen = Path.Combine(outputPath, fn, FNAME + ".pdf");
                            string savefile = Path.Combine(op_path, filen);

                            string pathString = getfilearray[f];
                            box = Path.GetDirectoryName(getfilearray[f]);
                            box1 = Path.GetDirectoryName(box);
                            using (GdPictureDocumentConverter oConverter = new GdPictureDocumentConverter()) {
                                GdPictureStatus status = new GdPictureStatus();
                                if (Path.GetExtension(getfilearray[f]).ToUpper() == ".PDF")
                                {
                                    status = oConverter.LoadFromFile(getfilearray[f], GdPicture14.DocumentFormat.DocumentFormatPDF);
                                }

                                else if (Path.GetExtension(getfilearray[f]).ToUpper() == ".TIF" || Path.GetExtension(getfilearray[f]).ToUpper() == ".TIFF")

                                {
                                    status = oConverter.LoadFromFile(getfilearray[f], GdPicture14.DocumentFormat.DocumentFormatTIFF);
                                }
                                else if (Path.GetExtension(getfilearray[f]).ToUpper() == ".JPG")
                                {
                                    status = oConverter.LoadFromFile(getfilearray[f], GdPicture14.DocumentFormat.DocumentFormatJPEG);
                                }

                                if (status == GdPictureStatus.OK)
                                {
                                    if (!Directory.Exists(op_path))
                                    {
                                        Directory.CreateDirectory(op_path);
                                    }
                                    GrantAccess(op_path);
                                    optPDFConform = (PdfConformance)((ComboBoxItem)cbPDFConform.SelectedItem).Tag;
                                    status = oConverter.SaveAsPDF(savefile, optPDFConform);
                                    if (status == GdPictureStatus.OK)
                                    { }
                                    else
                                    { }
                                }
                                else
                                { }
                            }
                        }
                    string BOXX = box.Replace(ip.Text, Protb.Text);
                    string[] Arr = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
                    if (MergeChk.IsChecked == true)
                    { merge(Arr); }
                    else if (MergeChk.IsChecked == false)
                    {
                        mutliocr(Arr);
                    }
                }
            }));
        }
        catch (Exception ee)
        { }                        
        return dir;
    }

    private string[] merge(string[] arr)
    {
        string box = string.Empty;
        string box1 = string.Empty; string[] gg = null;           
        System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
        {                                     
            box = Path.GetDirectoryName(arr[0]);
            box1 = Path.GetDirectoryName(box);
            string dirName = Directory.GetParent(arr[0]).FullName;
            string BOXFILES = Path.GetDirectoryName(dirName);
            string folder = Directory.GetParent(arr[0]).FullName.Replace(Protb.Text, op.Text);              
           
            string ocrfolder = (new FileInfo(arr[0]).Directory.FullName).Replace(Protb.Text, op.Text);
            string fn = Directory.GetParent(arr[0]).Name;
            string filen = Path.Combine(ocrfolder, folder, fn + ".pdf");
            if (!Directory.Exists(ocrfolder))
            {
                Directory.CreateDirectory(ocrfolder);
            }
            GrantAccess(ocrfolder);
            using (GdPicturePDF oGdPicturePDF = new GdPicturePDF())
            {
                GdPictureStatus status = oGdPicturePDF.MergeDocuments(ref arr, filen);

                if (status == GdPictureStatus.OK)
                { }
                else
                { }
                oGdPicturePDF.Dispose();
            }
        Directory.Delete(box, true);         
        string BOXX = box.Replace(Protb.Text, op.Text);//op            
        string[] files = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
        if (MergeChk.IsChecked == true)
        { mutliocr(files); }            
        }));
        return gg;
    }

    private void inbtn_Click(object sender, RoutedEventArgs e)
    {
        try
        { ip.Text = browseFolder(); }
        catch (Exception e7)
        { MessageBox.Show("e7" + e7.Message); }
    }
    private void obtn_Click(object sender, RoutedEventArgs e)
    {
        try
        { op.Text = browseFolder(); }
        catch (Exception e8)
        { MessageBox.Show("e8" + e8.Message); }
    }
    private void start_btn_Click(object sender, RoutedEventArgs e)
    {
        if (!bw.IsBusy)
        {
            // Cancel the asynchronous operation.
            this.bw.CancelAsync();

            // Disable the Cancel button.

            bw.RunWorkerAsync();
            start_btn.Content = "Stop";
            //this.Status.Content = "Running....";

        }
        else
        {
            bw.CancelAsync();
            start_btn.Content = "Start";
            //this.Status.Content = "Stopped....";

        }
    }
    private void pro_btn_Click(object sender, RoutedEventArgs e)
    {
        try
        { Protb.Text = browseFolder(); }
        catch (Exception e10)
        { MessageBox.Show("e10" + e10.Message); }
    }
    private void excep_Click(object sender, RoutedEventArgs e)
    {
        try
        { ex_tb.Text = browseFolder(); }
        catch (Exception e11)
        { MessageBox.Show("e111" + e11.Message); }
    }      

    private void WriteLn(string text)
    {
        logtb.Dispatcher.BeginInvoke(new Action(() =>
        {
            logtb.Text += text + Environment.NewLine;
        }));

        log_list.Add(text);
        log_cap = text + Environment.NewLine + log_cap;
        using (StreamWriter sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"FileProcessing_log.txt"), false))
        {
            foreach (string l in log_list)
                sw.WriteLine(l);
            sw.Close();
        }
    }
}

}

BackgroundWorker是将东西从 UI 线程中推出。 这样做了,但随后在Bw_DoWork你立即将事情推UI 线程,使用this.Dispatcher.Invoke ,它会阻止工作线程,直到现在在 UI 线程上运行的工作完成。

基本上:删除this.Dispatcher.Invoke调用,然后在 worker 上运行代码。 如果您需要触摸 UI,那么您需要在 UI 线程上处理这些位,但仅限于那些按钮。

同样,我怀疑mutliocr应该使用 dispatch invoke,它当然不应该将 UI 线程更改为后台线程( Thread.CurrentThread.IsBackground = true; )。

您的代码非常非常臭和丑陋。 您似乎完全没有遵循任何命名约定。 本地和班级成员是驼峰式和 PascalCase,有些根本不使用大小写,有些则使用下划线。 你真的应该仔细检查你的代码,考虑很多方面并清理它。 也有一些冗余。

你的一个非常糟糕的习惯是过度使用Dispatcher 例如,您创建一个后台线程并发布完整的! 此线程的工作返回到Dispatcher /UI 线程。 资源的巨大浪费并消除了任何多线程优势。
您不想将所有工作都放在Dispatcher 您想将 CPU 密集型 eork 卸载到后台线程。 您希望尽可能使用异步 API。 因为你想让 UI 保持响应。 Dispatcher是指 UI 线程。

一些非常重要的兴趣点

  • GrantAccess实现是对用户权限的严重安全侵犯。 不要修改访问规则。 而是过滤并忽略当前用户无权访问的资源。 特别重要的是,您永远不要将访问权限恢复到原始状态。
  • 作为一般规则:不要在后台线程上执行 IO 相关代码(例如,数据库、HTTP 流、文件 IO)。 请改用异步 API。 仅将线程用于 CPU 密集型工作(例如计算、转换)。
  • File有一个你应该经常使用的异步 API。 例如File.OpenRead返回一个FileStream ,它公开一个FileStream.ReadAsnyc成员。 如果在逐行读取文件时需要更多便利,则将FileStream包装到StreamReader / StreamWriter并使用StreamReader.ReadLineAsync成员
  • 为避免Dispatcher调用,请将所需的 UI 值作为参数传递给并发方法。 更好地使用数据绑定(这不会消除编写跨线程问题,但会使您的代码更具可读性并消除Dispatcher调用以读取值)。 看看下面重构的File_process方法。 它展示了如何将 UI 值作为参数传递给converttiffpdfreducer方法,然后该方法在后台线程上执行。
  • 考虑为converttiffpdfreducer()运行的converttiffpdfreducer()添加取消支持
  • 避免在IEnumerable上调用ToArrayToList 这些方法是立即执行最初延迟的 LINQ 查询的终结器。
  • 不要对EnumerateFiles及其ToList的结果调用ToArrayToList 这些方法用于提高性能,因为它们逐项返回文件系统对象。 如果您递归迭代整个文件系统结构,这一点尤其重要。 如果文件系统树很深很宽,调用ToArray将强制迭代完成,然后立即返回所有结果。 EnumerateFiles上的ToArray就像使用GetFiles 您应该检查完整的代码并正确重构它。 你总是用Enumerate XYZ 错!

》 EnumerateFiles 和 GetFiles 方法的区别如下: 使用 EnumerateFiles 时,可以在返回整个集合之前开始枚举名称集合。使用 GetFiles 时,必须等待整个名称数组返回后才能进行访问数组。因此,当您处理许多文件和目录时,EnumerateFiles 可以更高效。”

  • 使用数据绑定而不是直接访问 UI 元素。 这允许您在不使用Dispatcher情况下读取后台线程上的属性。
  • 永远不要从构造函数执行长时间运行的操作
  • 永远不要从构造函数调用异步代码
  • 始终保持对象实例化便宜且快速,并且没有隐藏的性能/资源成本
  • 永远不要捕获Exception 始终捕获专门的异常类型。
  • 不要使用空的 catch 块。 如果可以,要么处理异常,要么让它使您的应用程序崩溃,让您有机会修复错误。 当您吞下异常时,错误将悄悄地潜入您的应用程序。 你将很难发现它们。 记录异常不被视为处理 - 在这种情况下重新抛出。
  • 如果使用using语句声明资源,则不必显式关闭资源。 一旦指令指针离开using作用域,对Dispose的隐式调用将自动关闭资源。

实施所有建议将显着加快您的应用程序。

我只重构了你的一些代码来展示如何正确使用异步 API 和Task.Run而不是BackgroundWorker 我已经删除了每个Dispatcher调用。 我没有直接访问 UI 元素以从后台线程读取它们的值,而是在调用并发方法之前提取这些值并将这些预取值作为方法参数传递。 如果您将使用数据绑定,您可以直接读取属性值并因此省略方法参数。

MainWindow应从App.xaml.cs手动显示,以允许实例的异步和长时间运行初始化。 对于此模式,让需要此类初始化的类实现可以从调用者的上下文中等待的公共InitializeAsync方法。 或者,在需要时使用Lazy<T>推迟初始化,例如,当初始化依赖于对成员的显式访问时。

尽管重构的代码将显着提高应用程序的性能,但您必须自己进行一些重要的重构(遵循已重构代码部分的模式)。
看一眼

  • InitializeAsyncWriteLnAsync以了解如何使用异步文件 IO API。
  • converttiffpdfreducer了解如何正确使用EnumerateFilesEnumerateDirectories方法以显着提高性能。
  • mutliocrmergeconverttiffpdfreducer以了解如何将 UI 元素值作为参数传递以避免Dispatcher调用。
  • start_btn_Clickconverttiffpdfreducer了解如何实现取消并保护您的 API 在未初始化状态期间免受调用

应用程序.xaml

<Application Startup="Application_Startup">

</Application>

应用程序.xaml.cs

class App : Application
{
  private async void Application_Startup(object sender, StartupEventArgs e)
  {
    var mainWindow = new MainWindow();

    // Because InitializeAsync depends on UI elements,
    // we have to wait until the Ui is loaded.
    mainWindow.Loaded += OnMainWindowLoaded;

    // Either call Show() before initialization or after.
    // If before, ensure access to uninitialized members and resources is denied
    // e.g. by querying the MainWindow.IsInitialized property in public members and event handlers.
    mainWindow.Show();        
  }

  private async void OnMainWindowLoaded(object sender, EventArgs args) 
    => await mainWindow.InitializeAsync();
}

主窗口.xaml.cs

public partial class MainWindow : Window
{
  public bool IsInitialized { get; private set; }
  private bool IsBusy { get; set; }
  private CancellationTokenSource CancellationTokenSource { get; set; }

  public MainWindow()
  {
    InitializeComponent();
    CancellationTokenSource = new CancellationTokenSource();
  }

  // Execute blocking initialization routines asynchronously
  public async Task InitializeAsync()
  {
    if (IsInitialized)
    {
      return;
    }

    // Will execute the intesive CPU bound work on a background thread.
    await File_process(Cancellationtoken.None);

    string configpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"path.txt");
    // Use async API to read/write from/to files and other IO resources
    using (FileStream configfile = File.OpenRead(configpath))
    {
      using (var fileReader = new StreamReader(configfile))
      {
        var configFileContent = new List<string>();
        while (!fileReader.EndOfStream)
        {
          string lineOfFile = await fileReader.ReadLineAsync();
          configFileContent.Add(lineOfFile);
        }

        if (configFileContent.Any())
        {
          ip.Text = configFileContent[0];
          GrantAccess(configFileContent[0]);

          op.Text = configFileContent[1];
          GrantAccess(configFileContent[1]);

          ex_tb.Text = configFileContent[2];
          GrantAccess(configFileContent[2]);

          Protb.Text = configFileContent[3];
          GrantAccess(configFileContent[3]);
        }
      }
    }

    cbPDFConform.Items.Clear();
    for (int i = 0; i < Enum.GetNames(typeof(PdfConformance)).Length - 1; i++)
    {
      ComboBoxItem cbi = new ComboBoxItem();
      cbi.Content = Enum.GetName(typeof(PdfConformance), (PdfConformance)i);
      PdfConformance test = (PdfConformance)i;
      cbi.Tag = (PdfConformance)i;
      cbPDFConform.Items.Add(cbi);
    }

    cbPDFConform.SelectedIndex = 0;
    cbProcessorCount.Items.Clear();
    for (int i = 1; i <= Environment.ProcessorCount; i++)
    {
      cbProcessorCount.Items.Add(i.ToString());
      if (Environment.ProcessorCount / 2 == i) { cbProcessorCount.SelectedIndex = i - 1; }
    }

    LicenseManager oLicenseManager = new LicenseManager();
    oLicenseManager.RegisterKEY("");

    threadSyn = SynchronizationContext.Current;

    IsInitialiezd = true;
  }

  public async Task File_process(CancellationToken cancellationToken)
  {
    // Read UI values to avoid Dispatcher calls from the background thread
    string ipText = ip.Text;
    string protbText = Protb.Text;
    string opText = op.Text;

    // Execute the intesive CPU bound work on a background thread.
    await Task.Run(() => converttiffpdfreducer(ipText, protbText, opText, cancellationToken), cancellationToken);
  }

private async Task DoWorkAsync(CancellationToken cancellationToken)
{
  IsBusy = true;

  using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"path.txt"), false))
  {
    await sw.WriteLineAsync(ip.Text);
    await sw.WriteLineAsync(op.Text);
    await sw.WriteLineAsync(ex_tb.Text);
    await sw.WriteLineAsync(Protb.Text);
  }

  try
  {
    cancellationToken.ThrowIfCancellationRequested();

    var watch1 = new System.Diagnostics.Stopwatch();
    watch1.Start();

    // Consider to add cancellation support to File_process 
    await File_process(cancellationToken);

    watch1.Stop();

    TimeSpan ts1 = watch1.Elapsed;
    ts1.ToString("mm\\:ss");

    if (MergeChk.IsChecked == false)
    {
      value = "OCRed";
    }

    await WriteLnAsync("All documents have been successfully " + value + " " + ts1 + " " + DateTime.Now + " " + Environment.UserName, cancellationToken);

    IsBusy = false;
  }
  catch (OperationCanceledException)
  {
    IsBusy = false;
    throw;
  }
}

  private async Task WriteLnAsync(string text, CancellationToken cancellationToken)
  {
    logtb.Text += text + Environment.NewLine;

    log_list.Add(text);
    log_cap = text + Environment.NewLine + log_cap;
    using (var sw = new StreamWriter(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"FileProcessing_log.txt"), false))
    {
      foreach (string l in log_list)
      {
        cancellationToken.ThrowIfCancellationRequested();
        await sw.WriteLineAsync(l);
      }
    }
  }

  private async void start_btn_Click(object sender, RoutedEventArgs e)
  {
    if (!IsInitialized)
    {
      return;
    }

    if (IsBusy)
    {
      // Cancel the longrunning operation.
      this.CancellationTokenSource.Cancel();
    }
    start_btn.Content = "Start";

    try
    {
      await DoWorkAsync(CancellationTokenSource.Token);
    }
    catch (OperationCanceledException)
    {
      CancellationTokenSource?.Dispose();
      CancellationTokenSource = new CancellationTokenSource();
    }
  }

  private void converttiffpdfreducer(
    string ipText, 
    string protbText, 
    string opText, 
    CancellationToken cancellationToken)
  {
    string[] dir = null;
    string box = string.Empty;
    string box1 = string.Empty;
    string[] gg = null;


    PdfConformance optPDFConform = PdfConformance.Unknown;

    foreach (var directoryPath in Directory.EnumerateDirectories(ipText, "*.*", SearchOption.AllDirectories).Where(l => l.Length != 0))
    {
      cancellationToken.ThrowIfCancellationRequested();

      foreach (var filePath in Directory.EnumerateFiles(directoryPath, "*.*", SearchOption.AllDirectories))
      {
        cancellationToken.ThrowIfCancellationRequested();

        string getext = Path.GetExtension(filePath);
        string fd = Path.GetDirectoryName(filePath);
        string op_path = fd.Replace(ipText, protbText);
        string getextension = Path.GetExtension(filePath);
        string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
        string outputPath = fd.Replace(ipText, protbText);
        string FNAME = Path.GetFileNameWithoutExtension(filePath);
        string fn = Path.GetDirectoryName(filePath).Replace(ipText, protbText);
        string filen = Path.Combine(outputPath, fn, FNAME + ".pdf");
        string savefile = Path.Combine(op_path, filen);

        box = Path.GetDirectoryName(filePath);
        box1 = Path.GetDirectoryName(box);
        using (GdPictureDocumentConverter oConverter = new GdPictureDocumentConverter())
        {
          GdPictureStatus status = new GdPictureStatus();
          if (Path.GetExtension(filePath).ToUpper() == ".PDF")
          {
            status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatPDF);
          }

          else if (Path.GetExtension(filePath).ToUpper() == ".TIF" || Path.GetExtension(filePath).ToUpper() == ".TIFF")

          {
            status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatTIFF);
          }
          else if (Path.GetExtension(filePath).ToUpper() == ".JPG")
          {
            status = oConverter.LoadFromFile(filePath, GdPicture14.DocumentFormat.DocumentFormatJPEG);
          }

          if (status == GdPictureStatus.OK)
          {
            if (!Directory.Exists(op_path))
            {
              Directory.CreateDirectory(op_path);
            }
            GrantAccess(op_path);
            optPDFConform = (PdfConformance)((ComboBoxItem)cbPDFConform.SelectedItem).Tag;
            status = oConverter.SaveAsPDF(savefile, optPDFConform);
            if (status == GdPictureStatus.OK)
            { }
            else
            { }
          }
          else
          { }
        }
      }
    }

    string BOXX = box.Replace(ipText, protbText);

    // TODO::Refactor 'merge' and replace 'ToArray' with 'foreach'
    string[] Arr = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
    if (MergeChk.IsChecked == true)
    { merge(Arr, protbText); }
    else if (MergeChk.IsChecked == false)
    {
      mutliocr(Arr);
    }
  }

  private string[] merge(string[] arr, string protbText, string opText)
  {
    string box = string.Empty;
    string box1 = string.Empty; string[] gg = null;
    System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
    {
      box = Path.GetDirectoryName(arr[0]);
      box1 = Path.GetDirectoryName(box);
      string dirName = Directory.GetParent(arr[0]).FullName;
      string BOXFILES = Path.GetDirectoryName(dirName);
      string folder = Directory.GetParent(arr[0]).FullName.Replace(protbText, opText);

      string ocrfolder = (new FileInfo(arr[0]).Directory.FullName).Replace(protbText, opText);
      string fn = Directory.GetParent(arr[0]).Name;
      string filen = Path.Combine(ocrfolder, folder, fn + ".pdf");
      if (!Directory.Exists(ocrfolder))
      {
        Directory.CreateDirectory(ocrfolder);
      }
      GrantAccess(ocrfolder);
      using (GdPicturePDF oGdPicturePDF = new GdPicturePDF())
      {
        GdPictureStatus status = oGdPicturePDF.MergeDocuments(ref arr, filen);

        if (status == GdPictureStatus.OK)
        { }
        else
        { }
        oGdPicturePDF.Dispose();
      }
      Directory.Delete(box, true);
      string BOXX = box.Replace(protbText, opText);//op            
      string[] files = Directory.EnumerateFiles(BOXX, "*.pdf", SearchOption.AllDirectories).ToArray();
      if (MergeChk.IsChecked == true)
      { mutliocr(files, protbText, opText); }
    }));
    return gg;
  }

  private string[] mutliocr(string[] arr, string protbText, string opText)
  {
    string box = string.Empty;
    string box1 = string.Empty;
    try
    {
      string filepath = string.Empty;
      if (MergeChk.IsChecked == true)
      { filepath = opText; }
      else if (MergeChk.IsChecked == false)
      { filepath = protbText; }
      System.Windows.Threading.Dispatcher.CurrentDispatcher.Invoke((Action)(() =>
      {
        Thread.CurrentThread.IsBackground = true;
        var watch2 = new System.Diagnostics.Stopwatch();
        watch2.Start();
        string[] getfilearray = arr;
        for (int f = 0; f < getfilearray.Length; f++)
        {
          string dirName = Directory.GetParent(getfilearray[f]).FullName;
          string folder = Directory.GetParent(getfilearray[f]).FullName;

          box = Path.GetDirectoryName(getfilearray[f]);
          box1 = Path.GetDirectoryName(box);
          string getextension = Path.GetExtension(getfilearray[f]);
          string[] newF = Directory.EnumerateFiles(dirName, "*.*", SearchOption.AllDirectories).ToArray();
          string FN = Directory.GetParent(getfilearray[f]).Name;
          string ocrfolder = (new FileInfo(getfilearray[f]).Directory.FullName);
          string filen = Path.Combine(ocrfolder, folder, FN + "-ocr" + getextension);
          string dict = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Redist", "OCR");
          if (!Directory.Exists(ocrfolder))
          {
            Directory.CreateDirectory(ocrfolder);
          }
          GrantAccess(ocrfolder);
          GdPicturePDF oGdPicturePDF = new GdPicturePDF();
          oGdPicturePDF.OcrPagesDone += OcrPagesDone;
          void OcrPagesDone(GdPictureStatus status1)
          {
            if (oGdPicturePDF.SaveToFile(filen) == GdPictureStatus.OK)
            { }
            else
              MessageBox.Show("PDF: The OCR-ed file has failed to save. Status: " + oGdPicturePDF.GetStat().ToString());
          }
          GdPictureStatus status = GdPictureStatus.OK;
          if (oGdPicturePDF.LoadFromFile(getfilearray[f], false) == GdPictureStatus.OK)
            if (status == GdPictureStatus.OK)
            {
              if (oGdPicturePDF.OcrPages_4("*", 0, "eng", dict, "", 300, OCRMode.FavorSpeed, 1, true) == GdPictureStatus.OK)
                if (status == GdPictureStatus.OK)
                { }
                else
                { MessageBox.Show("PDF: The OCR process has failed. Status: " + status.ToString()); }
            }
            else
            { MessageBox.Show("PDF: The PDF file has failed to load. Status: " + status.ToString()); }

          oGdPicturePDF.Dispose();
          GrantAccess(getfilearray[f]);
          File.Delete(getfilearray[f]);
          watch2.Stop();
          TimeSpan ts2 = watch2.Elapsed;
          ts2.ToString("mm\\:ss");
          WriteLn(" OCR pages " + filen.Replace(opText, "") + " " + ts2 + " " + DateTime.Now);
        }
        if (MergeChk.IsChecked == true)
        {
          foreach (string str in Directory.EnumerateFiles(opText, "*.pdf", SearchOption.AllDirectories).ToArray())
          {
            if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
              File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
          }
        }
        if (MergeChk.IsChecked == false)
        {
          FileSystem.MoveDirectory(protbText, opText, UIOption.AllDialogs);
          Directory.CreateDirectory(protbText);
          string FF = string.Empty;
          foreach (string str in Directory.EnumerateFiles(opText, "*.pdf", SearchOption.AllDirectories))
          {

            if (Path.GetFileNameWithoutExtension(str).EndsWith("-ocr"))
              File.Move(str, Path.Combine(Path.GetDirectoryName(str), Path.GetFileNameWithoutExtension(str).Substring(0, Path.GetFileNameWithoutExtension(str).Length - 4) + ".pdf"));
          }
        }

      }));
    }
    catch (Exception mul)
    {
    }
    return arr;
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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