using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace WpfTestAcCoreConsole.Scripting
{
public class ScriptProcessor
{
public string AcCoreLocation { get; set; }
public string ScriptFilepath { get; set; }
public string Language { get; set; }
public string Isolate { get; set; }
private CancellationTokenSource CTokenSource;
private int MaxTime { get; set; }
private string Arguments(string drawingPath)
{
return String.Format("/i \"{0}\" /s \"{1}\" /l \"{2} \"/isolate\" {3}", drawingPath, ScriptFilepath,
Language, Isolate);
}
public ScriptProcessor(string acCoreLocation, string scriptFilePath, string isolate = "CoreConsole",
string language = "en-us")
{
AcCoreLocation = acCoreLocation;
ScriptFilepath = scriptFilePath;
Isolate = isolate;
Language = language;
CTokenSource
= new CancellationTokenSource
(); MaxTime = Properties.Settings.Default.MaxWaitTime * 1000;
}
private ProcessStartInfo CreateProcessStartInfo(FileInfo fi)
{
return new ProcessStartInfo
() {
FileName = AcCoreLocation,
Arguments = Arguments(fi.FullName),
UseShellExecute = false,
CreateNoWindow = true
};
}
public void Cancel()
{
CTokenSource.Cancel();
}
private ConcurrentQueue<FileInfo> fileQueue;
public async void ProcessFiles(ICollection<FileInfo> fileInfos, IProgress<ProgressInfo> pinfo)
{
fileQueue
= new ConcurrentQueue
<FileInfo
>(fileInfos
); int cores = Interop.User32.NumberOfCores();
Task
[] tasks
= new Task
[cores
]; for (int i = 0; i < cores; i++)
{
tasks[i] = RunAcCoreConsole(fileQueue, CTokenSource.Token, pinfo);
}
await Task.WhenAll(tasks);
}
private Task RunAcCoreConsole(ConcurrentQueue<FileInfo> que, CancellationToken ct, IProgress<ProgressInfo> pinfo)
{
return Task.Run(() =>
{
FileInfo file;
while (que.TryDequeue(out file))
{
ProgressInfo pi
= new ProgressInfo
(file
.FullName,
"Processing"); DateTime orgDateTime = file.LastWriteTimeUtc;
if (ct.IsCancellationRequested)
{
pi.Status = "Canceled";
return;
}
pinfo.Report(pi);
try
{
using (Process process
= new Process
()) {
process.StartInfo = CreateProcessStartInfo(file);
process.Start();
if (!process.WaitForExit(MaxTime))
{
pi.Status = "Max Time Reached";
process.CloseMainWindow();
if (!process.WaitForExit(2000))
{
process.Kill();
}
continue;
}
}
file.Refresh();
pi.Status = orgDateTime < file.LastWriteTimeUtc ? "Updated" : "Not Processed";
}
catch (Exception)
{
pi.Status = "Error";
}
}
}, ct);
}
}
}