在Observable()操作后删除文件

问题描述 投票:0回答:2

我在集合(Dictionary>)上运行了一些可观察的操作,其中字符串是作业名称,List是与该作业名称相关的文件。

如果我将List转换为Observable,它将按列表元素的数量运行所有操作。因此,在所有操作后我都可以删除文件。

为了避免这种情况,我将Dictionary键转换为另一个observable。但是当我这样做时,我无法删除与密钥相关的文件(值(列表))。

这有什么解决方法吗?我知道一旦所有操作完成,它将会点击订阅。但由于它在键上运行(所以它不会重复)我没有要删除的有效文件。

我尽可能详细地发布代码。

任何输入都表示赞赏。谢谢

if (TIFFFiles.Count > 0 && ThreadRunning == false) //If there are files to be processed and nothing is already running
            {
                ThreadRunning = true;
                var toObservable = TIFFFiles.ToObservable(); //Converting the current file list to an observable
                cmb_ColorDelimiter.UIThread(() => cmb_tiffSelectedIndex = cmb_ColorDelimiter.SelectedIndex); //An int value
                var ColorSeparator = new ColorSeparatorDefiner(cmb_tiffSelectedIndex).Delimiter;//An string value
                var InfoFromFiles = new List<CMYKJobInformationForDictionarySorting>();//List for sorting
                Dictionary<string, List<string>> AvailableJobsDictionary = new Dictionary<string, List<string>>(); //The dictionary where i sort the files received on TIFFFiles                    
                for (int i = 0; i < TIFFFiles.Count; i++)
                {
                    AvailableJobsDictionary = BuildJobsDict(TIFFFiles[i], ColorSeparator, AvailableJobsDictionary,InfoFromFiles); //The method that sorts the files from TIFFFiles
                }
                var observableKeys = AvailableJobsDictionary.Keys.ToObservable(); //Converting the dictiobary keys to an observable
                foreach(var item in AvailableJobsDictionary) //Looping trough sorted jobs
                {
                    //By iterating over the keys i can iterate only one time per job. If iterate over all TIFFFiles it will run operations by the number of elements available in TIFFFiles.
                    IObservable<string> query = from file in observableKeys 
                                                from WriteDefaultXML in Observable.Start(() => new PPFConverter.writeFinalXml(item.Key, tb_TIFFtoXMLOutputFolder.Text))
                                                from ImageListSorted in Observable.Start(() => ImageBuilder(item.Value, ColorSeparator))
                                                from DPI in Observable.Start(() => new ObtainDPI(item.Value.ElementAt(0)))
                                                from IZDataInfo in Observable.Start(() => new IZAreaDataInfo(izAreaSettings.FrmIZArea_numberOfZones, izAreaSettings.FrmIZArea_zoneWidth,
                                                izAreaSettings.FrmIZArea_firstZoneWidth, izAreaSettings.FrmIZArea_lastZoneWidth, izAreaSettings.FrmIZArea_zoneAreaWidth, izAreaSettings.FrmIZArea_zoneAreaHeight, DPI.DPI))
                                                from RotateCMYK in Observable.Start(() => Rotate(ImageListSorted.CMYKmages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageRotationCount))
                                                from RotateImposition in Observable.Start(() => Rotate(ImageListSorted.ImposedImages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageRotationCount))
                                                from IZDraw in Observable.Start(() => InkZoneAreaImage(IZDataInfo.IzArea_ZoneAreaWidth, IZDataInfo.IzArea_ZoneAreaHeight))
                                                from CMYKIZCalculation in Observable.Start(() => LevelCalc(IZDataInfo.IzArea_ZoneWidth, DPI.DPI, RotateCMYK.RotatedImgs, IZDraw.ZoneImage, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont))
                                                from ImposedIZCalculation in Observable.Start(() => LevelCalc(IZDataInfo.IzArea_ZoneWidth, DPI.DPI, RotateImposition.RotatedImgs, IZDraw.ZoneImage, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont))
                                                from CMYKResize in Observable.Start(() => ResizeCollection(RotateCMYK.RotatedImgs, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewWidth, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewHeight))
                                                from ImpositionResize in Observable.Start(() => ResizeCollection(RotateImposition.RotatedImgs, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewWidth, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewHeight))
                                                from CombineTHumbnail in Observable.Start(() => CombineImages(CMYKResize.ResizedImages, (bool)Properties.Settings.Default["TIFFtoXML_NegateImage"]))
                                                from CreateComposedImage in Observable.Start(() => new SpotImageComposer(CombineTHumbnail.FinalCombinedImage, ImpositionResize.ResizedImages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont, ColorSeparator, tiffToXmlpngPreviewSettings.TIffToXml_UnknownSpotcolorHandling))
                                                from FinalXMLWrite in Observable.Start(() => new WriteXMLData(WriteDefaultXML.finalXmlName,WriteDefaultXML.OutputFolder,CMYKIZCalculation,ImposedIZCalculation,CreateComposedImage.FinalImage,WriteDefaultXML.xmlDoc,InfoFromFiles,ColorSeparator,item.Value))
                                                select file;                        
                    if((bool)Properties.Settings.Default["TIFFtoXML_DeleteInput"])
                    {
                        _subscription = query.Subscribe(f => System.IO.File.Delete(f)); //Wanted to delete the files
                    }
                    TIFFFiles.Clear();
                    ThreadRunning = false;
                }

            }

更新的代码:

public partial class Form1
{
    Dictionary<string, List<string>> sortedJobs;
    Subject<List<string>> jobsToRun;
    private int cmb_tiffSelectedIndex;
    public Form1()
    {
        InitializeComponent();
        jobsToRun = new Subject<List<string>>();
        sortedJobs = new Dictionary<string, List<string>>();
    }
    private void SecondElapsed(object sender, EventArgs e)
    {
        counter--;
        if (counter == 0)
        {
            timer1.Stop();
            counter = Int32.Parse(internalSettings.TIFFtoXML_MainTimer);
            cmb_ColorDelimiter.UIThread(() => cmb_tiffSelectedIndex = cmb_ColorDelimiter.SelectedIndex); //An int value      
            foreach (var item in sortedJobs.Values) //Each list string contains information about an job and its respective files
            {
                jobsToRun.OnNext(item);
                IObservable<List<string>> query = from currItem in jobsToRun
                                                  let ColorSeparator = new ColorSeparatorDefiner(cmb_tiffSelectedIndex).Delimiter
                                                  let JobInfo = new CMYKJobInformationForDictionarySorting(item.ElementAt(0), ColorSeparator)
                                                  let file = JobInfo.ConventionName
                                                  select currItem;
                _subscription = query.Subscribe(x =>
                {
                    if ((bool)Properties.Settings.Default["TIFFtoXML_DeleteInput"])
                    {
                        foreach (var currFile in x)
                            File.Delete(currFile);
                            //Wanted to delete the files
                        }
                });
                string r = string.Empty;
            }
            timer1.Start();
        }
        tb_MainTimer.Text = counter.ToString();
    }
    private void TIFFtoXMLEventHandler(object sender, FileSystemEventArgs e)
    {
        string fNameExt = Path.GetExtension(e.FullPath).ToUpper();
        if (new GetAvailableFile(e.FullPath).fileReady)
        {
            if (fNameExt.Contains(".TIF"))
            {
                SortFilesOnArrival(e.FullPath, cmb_tiffSelectedIndex);
            }
            else if (fNameExt.Contains(".CIP") || fNameExt.Contains(".PPF"))
            {

            }
        }
        counter = Int32.Parse(internalSettings.TIFFtoXML_MainTimer);
        // timer1.Stop();
        timer1.Start();
    }
    private void SortFilesOnArrival(string currFile, int ColorDelimiterIndex)
    {
        var colorSeparator = new ColorSeparatorDefiner(ColorDelimiterIndex).Delimiter;
        CMYKJobInformationForDictionarySorting InfoFromFiles = new CMYKJobInformationForDictionarySorting(currFile, colorSeparator);
        if (sortedJobs.ContainsKey(InfoFromFiles.ConventionName))
        {
            sortedJobs[InfoFromFiles.ConventionName].Add(InfoFromFiles.OriginalFileName);
        }
        else
        {
            sortedJobs.Add(InfoFromFiles.ConventionName, new List<string>() { InfoFromFiles.OriginalFileName });
        }
        FilesCopiedInfo.Add(InfoFromFiles);
    }
}

更新:我编辑了包括我所做的一切的最终代码=)!它最终工作,现在我只是设置一些细节(更多关于业务逻辑和工作流程)。我知道这远远不是好事,但就目前我决定要做的事情而言。我的下一个目标是对所有类型的文件进行单一订阅,并处理查询本身的不同情况;它会使事情变得更容易,并允许我用更少的代码做同样的事情。并提前感谢您的帮助。这就像是对我的Reactive Extensions的介绍嘿,我开始阅读和挖掘它。

public partial class Form1 : AsyncBaseDialog
{
        private IDisposable CIP3Subscription = null;
        static System.Windows.Forms.Timer timer1; //The timer is used but just for visual purposes - nothing is related to him
        IObservable<FileSystemEventArgs> TIFFFilesCreated;
        IObservable<FileSystemEventArgs[]> TIFFGroupFiles;
        IObservable<FileSystemEventArgs> CIP3FilesCreated;
        IObservable<FileSystemEventArgs[]> CIP3GroupFiles;
        bool currStatus = (bool)Properties.Settings.Default["TIFFtoXML_EnabledConversion"]; //If the enable conversion checkbox is enabled, fire the observable
            if(currStatus)
            {
                EnableTIFFtoXMLWatcher(currStatus); 
                EnableCIP3toTIFFWatcher(currStatus);
            }
            timer1 = new System.Windows.Forms.Timer();
            timer1.Tick += new EventHandler(SecondElapsed);
            timer1.Enabled = currStatus;
            counter = Convert.ToInt32(Properties.Settings.Default.TIFFtoXML_MainTimer);
}        
 #region timerStuff
        DateTime start;
        double s;
        private void CountDown()
        {
            start = DateTime.Now;
            s = (double)counter;        
            timer1.Start();
        }
        private void SecondElapsed(object sender, EventArgs e)
        {
            double remainingSeconds = s - (DateTime.Now - start).TotalSeconds;
            if (remainingSeconds <= 0)
            {
                timer1.Stop();
                timer1.Interval = (int)counter;
                timer1.Start();
                CountDown();
            }
            var x = TimeSpan.FromSeconds(remainingSeconds);
            tb_MainTimer.Text = x.Seconds.ToString();
        }
        #endregion
        #region ObservableMethods //Methods i built in order to handle the observable behaviour
        private IObservable<FileSystemEventArgs[]> CreateObjectForConvertAll(string inputFolder, string extension)
        {            
        //I've a checkbox where the user selects "Convert all", and it will convert everything in the folder. Since i didn't wanted to repeat
        //code by calling all methods again, this method returns me an object i can query

            List<FileSystemEventArgs> tempList = new List<FileSystemEventArgs>(Directory.GetFiles(tb_TIFFtoXMLInputFolder.Text, extension, SearchOption.TopDirectoryOnly).ToList()
                            .Select(x => new FileSystemEventArgs(WatcherChangeTypes.Created, "", x)));
            List<FileSystemEventArgs[]> fswArgsArrayList = new List<FileSystemEventArgs[]>();           
            fswArgsArrayList.Add(tempList.ToArray());
            var finalObservable = fswArgsArrayList.ToArray();
            var finalObservableNotArray = finalObservable.ToArray().ToObservable();
            return finalObservableNotArray;
        }
        private IObservable<FileSystemEventArgs> CreateReactiveFSWInstance(string inputFolder, string fileFilter, bool checkBoxStatus)
        {
            //Creates the Reactive FSW instance
            //checkBoxStatus => Enabled or not ; if the user enables the conversion, EnableRaisingEvents will be true
            IObservable<FileSystemEventArgs> filesCreated =
    Observable
        .Using(
            () =>
            {
                var fsw = new FileSystemWatcher(inputFolder)
                {
                    EnableRaisingEvents = checkBoxStatus,
                    Filter = fileFilter
                };
                return fsw;
            },
            fsw => Observable.FromEventPattern
                <FileSystemEventHandler, FileSystemEventArgs>(
                h => fsw.Created += h,
                h => fsw.Created -= h))
        .Delay(TimeSpan.FromSeconds(0.1))
        .Select(x => x.EventArgs);
            return filesCreated;
        }        
        private IObservable<FileSystemEventArgs[]> TIFFPublish(IObservable<FileSystemEventArgs> observable)
        {
            var GroupFiles =
                 observable
                     .Publish(fc =>
                         from w in fc.Window(() => fc.Throttle(TimeSpan.FromSeconds((double)counter)))
                         from fcs in w.ToArray()
                         select fcs);
            return GroupFiles;
        }
        #endregion 
        private void StartCIP3ProcessingQuery(IObservable<FileSystemEventArgs[]> Files)
        {
            //query goes here...
        }
         private void StartTIFFProcessingQuery(IObservable<FileSystemEventArgs[]> Files)
        {
            //query goes here...
        }
        private void EnableTIFFtoXMLWatcher(bool status)
        {
            //Enable the reactive watcher for TIF files
            TIFFFilesCreated = CreateReactiveFSWInstance(tb_TIFFtoXMLInputFolder.Text, "*.tif", status);
            TIFFGroupFiles = TIFFPublish(TIFFFilesCreated);
            StartTIFFProcessingQuery(TIFFGroupFiles);
        }
        private void EnableCIP3toTIFFWatcher(bool status)
        {
            //Enable the reactive watcher for CIP3 files
            CIP3FilesCreated = CreateReactiveFSWInstance(tb_TIFFtoXMLInputFolder.Text, "*.*", status);
            CIP3GroupFiles = TIFFPublish(CIP3FilesCreated);
            StartCIP3ProcessingQuery(CIP3GroupFiles, false);
        }
        private void SubscriptionDisposal()
        {
            //Disposal methods
            TIFFSubscription.Dispose();
            CIP3Subscription.Dispose();
        }
        //Enable or disable the conversio, or convert all
        private void CheckboxChangedEventHandler(object sender, EventArgs e)
        {
            CheckBox CurrChk = sender as CheckBox;
            bool status = CurrChk.Checked;
            switch (CurrChk.Name)
            {
                case "TIFFtoXML_chkConvertAll":
                    {
                        if(status)
                        {
                           cb_enableTIFFtoXML.Checked = true; //Enabling this checkbox triggers the other case and fires the FSW
                            var convertAllTIFFObj = CreateObjectForConvertAll(tb_TIFFtoXMLInputFolder.Text, "*.tif");
                            StartTIFFProcessingQuery(convertAllTIFFObj);
                            var convertAllCIP3Obj = CreateObjectForConvertAll(tb_TIFFtoXMLInputFolder.Text, "*.*");
                            StartCIP3ProcessingQuery(convertAllCIP3Obj,true);                            
                            CurrChk.Checked = false;
                        }        
                        break;
                    }
                case "cb_enableTIFFtoXML":
                    {
                        if (status)
                        {
                            EnableCIP3toTIFFWatcher(status);
                            EnableTIFFtoXMLWatcher(status);
                            CountDown();
                        }
                        else
                        {
                            //If the user disables the conversion, it will just dispose objects.
                            TIFFSubscription.Dispose();
                            CIP3Subscription.Dispose();
                            timer1.Stop();
                        }

                        break;
                    }
            }
        }
c# observable system.reactive
2个回答
1
投票

以下是您的代码应该更接近的版本:

IObservable<string> query =
    from item in TIFFFiles // TIFFFiles = new Subject<string>()
    let ColorSeparator = new ColorSeparatorDefiner(cmb_tiffSelectedIndex).Delimiter
    let jobInfo = new CMYKJobInformationForDictionarySorting(currFile, ColorSeparator)
    let file = jobInfo.ConventionName
    from WriteDefaultXML in Observable.Start(() => new PPFConverter.writeFinalXml(item.Key, tb_TIFFtoXMLOutputFolder.Text))
    from ImageListSorted in Observable.Start(() => ImageBuilder(item.Value, ColorSeparator))
    from DPI in Observable.Start(() => new ObtainDPI(item.Value.ElementAt(0)))
    from IZDataInfo in Observable.Start(() => new IZAreaDataInfo(izAreaSettings.FrmIZArea_numberOfZones, izAreaSettings.FrmIZArea_zoneWidth, izAreaSettings.FrmIZArea_firstZoneWidth, izAreaSettings.FrmIZArea_lastZoneWidth, izAreaSettings.FrmIZArea_zoneAreaWidth, izAreaSettings.FrmIZArea_zoneAreaHeight, DPI.DPI))
    from RotateCMYK in Observable.Start(() => Rotate(ImageListSorted.CMYKmages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageRotationCount))
    from RotateImposition in Observable.Start(() => Rotate(ImageListSorted.ImposedImages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageRotationCount))
    from IZDraw in Observable.Start(() => InkZoneAreaImage(IZDataInfo.IzArea_ZoneAreaWidth, IZDataInfo.IzArea_ZoneAreaHeight))
    from CMYKIZCalculation in Observable.Start(() => LevelCalc(IZDataInfo.IzArea_ZoneWidth, DPI.DPI, RotateCMYK.RotatedImgs, IZDraw.ZoneImage, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont))
    from ImposedIZCalculation in Observable.Start(() => LevelCalc(IZDataInfo.IzArea_ZoneWidth, DPI.DPI, RotateImposition.RotatedImgs, IZDraw.ZoneImage, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont))
    from CMYKResize in Observable.Start(() => ResizeCollection(RotateCMYK.RotatedImgs, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewWidth, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewHeight))
    from ImpositionResize in Observable.Start(() => ResizeCollection(RotateImposition.RotatedImgs, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewWidth, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewHeight))
    from CombineTHumbnail in Observable.Start(() => CombineImages(CMYKResize.ResizedImages, (bool)Properties.Settings.Default["TIFFtoXML_NegateImage"]))
    from CreateComposedImage in Observable.Start(() => new SpotImageComposer(CombineTHumbnail.FinalCombinedImage, ImpositionResize.ResizedImages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont, ColorSeparator, tiffToXmlpngPreviewSettings.TIffToXml_UnknownSpotcolorHandling))
    from FinalXMLWrite in Observable.Start(() => new WriteXMLData(WriteDefaultXML.finalXmlName, WriteDefaultXML.OutputFolder, CMYKIZCalculation, ImposedIZCalculation, CreateComposedImage.FinalImage, WriteDefaultXML.xmlDoc, InfoFromFiles, ColorSeparator, item.Value))
    select file;

_subscription =
    query
        .Subscribe(f =>
        {
            if ((bool)Properties.Settings.Default["TIFFtoXML_DeleteInput"])
            {
                System.IO.File.Delete(f); //Wanted to delete the files
            }
        }, () =>
        {
            /* code to execute when observable finishes */
            /* You must call `TIFFFiles.OnCompleted()` */
        });

请不要使用任何计时器,线程或任务。如果您确实说出了原因,我可以帮助您根据需要进行修复。

当您致电:TIFFFiles.OnNext(filename);时,所有这些都会被触发。


这是观察文件系统的代码,然后根据没有添加其他文件的TimeSpan.FromSeconds(30.0)将更改分组在一起:

IObservable<FileSystemEventArgs> filesCreated =
    Observable
        .Using(
            () =>
            {
                var fsw = new FileSystemWatcher(@"C:\Users\james\Temporary\Testing");
                fsw.EnableRaisingEvents = true;
                return fsw;
            },
            fsw => Observable.FromEventPattern
                <FileSystemEventHandler, FileSystemEventArgs>(
                h => fsw.Created += h,
                h => fsw.Created -= h))
        .Delay(TimeSpan.FromSeconds(0.1))
        .Select(x => x.EventArgs);

IObservable<FileSystemEventArgs[]> batchesOfFilesCreated =
    filesCreated
        .Publish(fc =>
            from w in fc.Window(() => fc.Throttle(TimeSpan.FromSeconds(30.0)))
            from fcs in w.ToArray()
            select fcs);

现在您的查询如下所示:

var ColorSeparator = new ColorSeparatorDefiner(cmb_tiffSelectedIndex).Delimiter;

var query =
    from gfcs in batchesOfFilesCreated.GroupBy(x => new CMYKJobInformationForDictionarySorting(currFile, ColorSeparator).ConventionName)
    let file = gfcs.Key
    from gfc in gfcs
    from WriteDefaultXML in Observable.Start(() => new PPFConverter.writeFinalXml(item.Key, tb_TIFFtoXMLOutputFolder.Text))
    from ImageListSorted in Observable.Start(() => ImageBuilder(item.Value, ColorSeparator))
    from DPI in Observable.Start(() => new ObtainDPI(item.Value.ElementAt(0)))
    from IZDataInfo in Observable.Start(() => new IZAreaDataInfo(izAreaSettings.FrmIZArea_numberOfZones, izAreaSettings.FrmIZArea_zoneWidth, izAreaSettings.FrmIZArea_firstZoneWidth, izAreaSettings.FrmIZArea_lastZoneWidth, izAreaSettings.FrmIZArea_zoneAreaWidth, izAreaSettings.FrmIZArea_zoneAreaHeight, DPI.DPI))
    from RotateCMYK in Observable.Start(() => Rotate(ImageListSorted.CMYKmages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageRotationCount))
    from RotateImposition in Observable.Start(() => Rotate(ImageListSorted.ImposedImages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageRotationCount))
    from IZDraw in Observable.Start(() => InkZoneAreaImage(IZDataInfo.IzArea_ZoneAreaWidth, IZDataInfo.IzArea_ZoneAreaHeight))
    from CMYKIZCalculation in Observable.Start(() => LevelCalc(IZDataInfo.IzArea_ZoneWidth, DPI.DPI, RotateCMYK.RotatedImgs, IZDraw.ZoneImage, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont))
    from ImposedIZCalculation in Observable.Start(() => LevelCalc(IZDataInfo.IzArea_ZoneWidth, DPI.DPI, RotateImposition.RotatedImgs, IZDraw.ZoneImage, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont))
    from CMYKResize in Observable.Start(() => ResizeCollection(RotateCMYK.RotatedImgs, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewWidth, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewHeight))
    from ImpositionResize in Observable.Start(() => ResizeCollection(RotateImposition.RotatedImgs, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewWidth, tiffToXmlpngPreviewSettings.FrmTiffPng_imagePreviewHeight))
    from CombineTHumbnail in Observable.Start(() => CombineImages(CMYKResize.ResizedImages, (bool)Properties.Settings.Default["TIFFtoXML_NegateImage"]))
    from CreateComposedImage in Observable.Start(() => new SpotImageComposer(CombineTHumbnail.FinalCombinedImage, ImpositionResize.ResizedImages, tiffToXmlpngPreviewSettings.FrmTiffPng_imageOrientationCont, ColorSeparator, tiffToXmlpngPreviewSettings.TIffToXml_UnknownSpotcolorHandling))
    from FinalXMLWrite in Observable.Start(() => new WriteXMLData(WriteDefaultXML.finalXmlName, WriteDefaultXML.OutputFolder, CMYKIZCalculation, ImposedIZCalculation, CreateComposedImage.FinalImage, WriteDefaultXML.xmlDoc, InfoFromFiles, ColorSeparator, item.Value))
    select file;

_subscription =
    query
        .Subscribe(f =>
        {
            if ((bool)Properties.Settings.Default["TIFFtoXML_DeleteInput"])
            {
                System.IO.File.Delete(f); //Wanted to delete the files
        }
        }, () =>
        {
        /* code to execute when observable finishes */
        /* You must call `TIFFFiles.OnCompleted()` */
        });

注意:这消除了代码中的计时器和线程的使用。您应该能够将其设置一次并使其保持运行状态。只要记得在你希望它停止运行时调用_subscription.Dispose()


0
投票

更新:我编辑了包括我所做的一切的最终代码=)!它最终工作,现在我只是设置一些细节(更多关于业务逻辑和工作流程)。我知道这远远不是好事,但就目前我决定要做的事情而言。

我的下一个目标是对所有类型的文件进行单一订阅,并处理查询本身的不同情况;它会使事情变得更容易,并允许我用更少的代码做同样的事情。并提前感谢您的帮助。这就像是对我的Reactive Extensions的介绍嘿,我开始阅读和挖掘它。

public partial class Form1 : AsyncBaseDialog
{
        private IDisposable CIP3Subscription = null;
        static System.Windows.Forms.Timer timer1; //The timer is used but just for visual purposes - nothing is related to him
        IObservable<FileSystemEventArgs> TIFFFilesCreated;
        IObservable<FileSystemEventArgs[]> TIFFGroupFiles;
        IObservable<FileSystemEventArgs> CIP3FilesCreated;
        IObservable<FileSystemEventArgs[]> CIP3GroupFiles;
        bool currStatus = (bool)Properties.Settings.Default["TIFFtoXML_EnabledConversion"]; //If the enable conversion checkbox is enabled, fire the observable
            if(currStatus)
            {
                EnableTIFFtoXMLWatcher(currStatus); 
                EnableCIP3toTIFFWatcher(currStatus);
            }
            timer1 = new System.Windows.Forms.Timer();
            timer1.Tick += new EventHandler(SecondElapsed);
            timer1.Enabled = currStatus;
            counter = Convert.ToInt32(Properties.Settings.Default.TIFFtoXML_MainTimer);
}        
 #region timerStuff
        DateTime start;
        double s;
        private void CountDown()
        {
            start = DateTime.Now;
            s = (double)counter;        
            timer1.Start();
        }
        private void SecondElapsed(object sender, EventArgs e)
        {
            double remainingSeconds = s - (DateTime.Now - start).TotalSeconds;
            if (remainingSeconds <= 0)
            {
                timer1.Stop();
                timer1.Interval = (int)counter;
                timer1.Start();
                CountDown();
            }
            var x = TimeSpan.FromSeconds(remainingSeconds);
            tb_MainTimer.Text = x.Seconds.ToString();
        }
        #endregion
        #region ObservableMethods //Methods i built in order to handle the observable behaviour
        private IObservable<FileSystemEventArgs[]> CreateObjectForConvertAll(string inputFolder, string extension)
        {            
        //I've a checkbox where the user selects "Convert all", and it will convert everything in the folder. Since i didn't wanted to repeat
        //code by calling all methods again, this method returns me an object i can query

            List<FileSystemEventArgs> tempList = new List<FileSystemEventArgs>(Directory.GetFiles(tb_TIFFtoXMLInputFolder.Text, extension, SearchOption.TopDirectoryOnly).ToList()
                            .Select(x => new FileSystemEventArgs(WatcherChangeTypes.Created, "", x)));
            List<FileSystemEventArgs[]> fswArgsArrayList = new List<FileSystemEventArgs[]>();           
            fswArgsArrayList.Add(tempList.ToArray());
            var finalObservable = fswArgsArrayList.ToArray();
            var finalObservableNotArray = finalObservable.ToArray().ToObservable();
            return finalObservableNotArray;
        }
        private IObservable<FileSystemEventArgs> CreateReactiveFSWInstance(string inputFolder, string fileFilter, bool checkBoxStatus)
        {
            //Creates the Reactive FSW instance
            //checkBoxStatus => Enabled or not ; if the user enables the conversion, EnableRaisingEvents will be true
            IObservable<FileSystemEventArgs> filesCreated =
    Observable
        .Using(
            () =>
            {
                var fsw = new FileSystemWatcher(inputFolder)
                {
                    EnableRaisingEvents = checkBoxStatus,
                    Filter = fileFilter
                };
                return fsw;
            },
            fsw => Observable.FromEventPattern
                <FileSystemEventHandler, FileSystemEventArgs>(
                h => fsw.Created += h,
                h => fsw.Created -= h))
        .Delay(TimeSpan.FromSeconds(0.1))
        .Select(x => x.EventArgs);
            return filesCreated;
        }        
        private IObservable<FileSystemEventArgs[]> TIFFPublish(IObservable<FileSystemEventArgs> observable)
        {
            var GroupFiles =
                 observable
                     .Publish(fc =>
                         from w in fc.Window(() => fc.Throttle(TimeSpan.FromSeconds((double)counter)))
                         from fcs in w.ToArray()
                         select fcs);
            return GroupFiles;
        }
        #endregion 
        private void StartCIP3ProcessingQuery(IObservable<FileSystemEventArgs[]> Files)
        {
            //query goes here...
        }
         private void StartTIFFProcessingQuery(IObservable<FileSystemEventArgs[]> Files)
        {
            //query goes here...
        }
        private void EnableTIFFtoXMLWatcher(bool status)
        {
            //Enable the reactive watcher for TIF files
            TIFFFilesCreated = CreateReactiveFSWInstance(tb_TIFFtoXMLInputFolder.Text, "*.tif", status);
            TIFFGroupFiles = TIFFPublish(TIFFFilesCreated);
            StartTIFFProcessingQuery(TIFFGroupFiles);
        }
        private void EnableCIP3toTIFFWatcher(bool status)
        {
            //Enable the reactive watcher for CIP3 files
            CIP3FilesCreated = CreateReactiveFSWInstance(tb_TIFFtoXMLInputFolder.Text, "*.*", status);
            CIP3GroupFiles = TIFFPublish(CIP3FilesCreated);
            StartCIP3ProcessingQuery(CIP3GroupFiles, false);
        }
        private void SubscriptionDisposal()
        {
            //Disposal methods
            TIFFSubscription.Dispose();
            CIP3Subscription.Dispose();
        }
        //Enable or disable the conversio, or convert all
        private void CheckboxChangedEventHandler(object sender, EventArgs e)
        {
            CheckBox CurrChk = sender as CheckBox;
            bool status = CurrChk.Checked;
            switch (CurrChk.Name)
            {
                case "TIFFtoXML_chkConvertAll":
                    {
                        if(status)
                        {
                           cb_enableTIFFtoXML.Checked = true; //Enabling this checkbox triggers the other case and fires the FSW
                            var convertAllTIFFObj = CreateObjectForConvertAll(tb_TIFFtoXMLInputFolder.Text, "*.tif");
                            StartTIFFProcessingQuery(convertAllTIFFObj);
                            var convertAllCIP3Obj = CreateObjectForConvertAll(tb_TIFFtoXMLInputFolder.Text, "*.*");
                            StartCIP3ProcessingQuery(convertAllCIP3Obj,true);                            
                            CurrChk.Checked = false;
                        }        
                        break;
                    }
                case "cb_enableTIFFtoXML":
                    {
                        if (status)
                        {
                            EnableCIP3toTIFFWatcher(status);
                            EnableTIFFtoXMLWatcher(status);
                            CountDown();
                        }
                        else
                        {
                            //If the user disables the conversion, it will just dispose objects.
                            TIFFSubscription.Dispose();
                            CIP3Subscription.Dispose();
                            timer1.Stop();
                        }

                        break;
                    }
            }
        }
© www.soinside.com 2019 - 2024. All rights reserved.