调用方法不起作用

时间:2018-06-28 07:55:23

标签: c# user-interface controls invoke

我的Winforms C#程序有问题。当文件从本地磁盘复制到网络磁盘时,我想显示一个进度条,但是它不起作用。我究竟做错了什么?

一旦我在WPF中遇到了这个问题,那么我就使用'Dispatcher'解决了它,但是在Winforms中,我猜没有类似的东西。下面的代码,谢谢您的帮助。

private void copyFiles(string SourcePath, string DestinationPath)
{
        string SourcePath, DestinationPath;
        int i = 0, idOperatDetail, udane = 0;
        OperatDetail operatDetail = null;

        if (circularProgressBar1.InvokeRequired)
        {
            circularProgressBar1.BeginInvoke((Action)(() => circularProgressBar1.Enabled = true));
            circularProgressBar1.BeginInvoke((Action)(() => circularProgressBar1.Visible = true));
            circularProgressBar1.BeginInvoke((Action)(() => circularProgressBar1.Style = ProgressBarStyle.Marquee));
        }
        else
        {
            circularProgressBar1.Enabled = true;
            circularProgressBar1.Visible = true;
        }

        foreach (string sourceFile in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".jpg") || s.EndsWith(".tif")))
        {
            i++;
        }

        if (i != 0)
        {
            // Jest urobek to utworz foldery
            foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories))
            {
                if (!Directory.Exists(dirPath.Replace(SourcePath, DestinationPath)))
                {
                    Directory.CreateDirectory(dirPath.Replace(SourcePath, DestinationPath));                        
                }
            }

            foreach (string sourceFile in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories).Where(s => s.EndsWith(".jpg") || s.EndsWith(".tif")))
            {
                string tempSchemat = sourceFile.Replace(SourcePath, "");
                var txt = tempSchemat.Split(new[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
                string schemat = "digitalizacja_" + txt[0].ToLower();

                if (operatDetailsUtils.DidDatabaseExists(schemat) == 0)
                {
                    operatDetail = operatDetailsUtils.GetOperatDetailIdByPath(schemat, sourceFile); // Pobierz ten szczegół z bazy danych
                    if (operatDetail != null) //  If file have record in database then get its metadata
                    {
                        idOperatDetail = operatDetail.Id;
                        Image img = Image.FromFile(sourceFile);
                        long size = (new FileInfo(sourceFile).Length);
                        int width = img.Width;
                        int height = img.Height;
                        float horResolution = img.HorizontalResolution;
                        float verResolution = img.VerticalResolution;
                        img.Dispose();
                        string destinationFile = sourceFile.Replace(SourcePath, DestinationPath);
                      //  if (size < FreeSpace(DestinationPath)) // Walidacja rozmiaru pliku kopiowanego
                        {
                                File.Copy(sourceFile, destinationFile, true);
                                Image imgDest = Image.FromFile(destinationFile);
                                long sizeDest = (new FileInfo(destinationFile).Length);
                                int widthDest = imgDest.Width;
                                int heightDest = imgDest.Height;
                                float horResolutionDest = imgDest.HorizontalResolution;
                                float verResolutionDest = imgDest.VerticalResolution;
                                imgDest.Dispose(); // Porównanie metadanych
                                if ((size != sizeDest) || (width != widthDest) || (height != heightDest) || (horResolution != horResolutionDest) || (verResolution != verResolutionDest))
                                {
                                    File.Delete(destinationFile); // Metadane sie nie zgadzaja
                                    slog.Error($"Plik o scieżce {destinationFile} ma inne metadane niż {sourceFile}. Został on usunięty ze względu na to, że został źle skopiowany");
                                }
                                else
                                {
                                    udane++;
                                    operatDetailsUtils.UpdatePath(schemat, idOperatDetail, destinationFile);
                                    File.Delete(sourceFile);
                                    slog.Info($"Plik {sourceFile} został poprawnie skopiowany na dysk sieciowy, a więc został usunięty z dysku lokalnego.");
                                }
                        }
                    }
                    else
                    {
                        slog.Error($"W bazie danych {schemat} w tabeli OPERAT_SZCZEGOLY nie istnieje plik o ścieżce {sourceFile} i nie został on skopiowany");
                    }
                }
                else
                {
                    slog.Error($"Baza danych {schemat} nie istnieje!");
                }
            }

            circularProgressBar1.BeginInvoke((Action)(() => circularProgressBar1.Enabled = false));
            circularProgressBar1.BeginInvoke((Action)(() => circularProgressBar1.Visible = false));                      
    }

2 个答案:

答案 0 :(得分:0)

我不明白为什么您要问是否需要Invoke,如果要从单独的线程访问GUI,请提出该要求。

将每个GUI更改方法放在invoke方法内,它应该可以工作。

赞:

this.Invoke(new Action(() =>
            {
                ProgressBar1.Value = ProgressPercentage;
            }));

答案 1 :(得分:-1)

尝试清理您的代码。另外,尝试在按钮事件中调用该方法。调用它:

Task name = Task( ()=> copyFiles("Source File"," Destination File"););
name.Start();

更新2:否?艰难的人群。无论如何,我认为只需删除您的图片类。这似乎在消耗整个任务。如果您只是将其用于验证,我认为FileInfo.Length已经足够了。

更新1 :除了数据库部分,我已经尝试了您的代码,进度条对我有用。

        private void copyFiles(string SourcePath, string DestinationPath)
        {
            List<string> ext = new List<string>() { ".JPG", ".JPEG", ".TIF", ".PNG" };
            DirectoryInfo di = new DirectoryInfo(SourcePath);

            Action shower = () =>
            {
                circularProgressBar1.Enabled = true;
                circularProgressBar1.Visible = true;
                circularProgressBar1.Style = ProgressBarStyle.Marquee;
            };
            BeginInvoke(shower);

            var sourceFiles = di.GetFiles("*.*",SearchOption.AllDirectories).Where(f => ext.Contains(f.Extension));
            int num = sourceFiles.Count();

            foreach(FileInfo fi in sourceFiles)
            {
                string newFilePath;
                if (!Directory.Exists(DestinationPath))
                {
                    Directory.CreateDirectory(DestinationPath);
                }
                newFilePath = Path.Combine(DestinationPath, fi.Name);

                File.Copy(fi.FullName, newFilePath, true);

                if(fi.Length != new FileInfo(newFilePath).Length)
                {
                    File.Delete(newFilePath);
                }
            }

            Action hider = () =>
            {
                circularProgressBar1.Enabled = false;
                circularProgressBar1.Visible = false;
                circularProgressBar1.Style = ProgressBarStyle.Continuous;
            };

            BeginInvoke(hider);
        }