324 lines
9.4 KiB
C#
324 lines
9.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
//using System.Windows.Forms;
|
|
using ChamChat.Models;
|
|
|
|
namespace ChamChat
|
|
{
|
|
public abstract class Task
|
|
{
|
|
private static string _LogFilePath;
|
|
|
|
private string _EventLogFile;
|
|
private string _DataTransferLogFile;
|
|
public static void SetLogPath(String path)
|
|
{
|
|
|
|
_LogFilePath = path + "\\TaskLogs";
|
|
|
|
if (!Directory.Exists(_LogFilePath))
|
|
Directory.CreateDirectory(_LogFilePath);
|
|
}
|
|
|
|
|
|
|
|
public Task(Client Client, Profile Profile)
|
|
{
|
|
_Profile = Profile;
|
|
_Client = Client;
|
|
ThreadPool.SetMaxThreads(1000, 1000);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitDataTransferLog()
|
|
{
|
|
try
|
|
{
|
|
_Client.DataTransferLogs = new List<DataTransferLog>();
|
|
|
|
DateTime dt = DateTime.Now;
|
|
_DataTransferLogFile = _LogFilePath + "\\" + string.Format("Task_{0:00000}_{1:0000}{2:00}{3:00}.{4:00}{5:00}{6:00}.csv", _Client.MIDS, dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
|
|
|
|
using (StreamWriter sw = File.CreateText(_DataTransferLogFile))
|
|
{
|
|
sw.WriteLine(string.Format("Client : {0}", _Client.ToString()));
|
|
sw.WriteLine(string.Format("Created : {0:0000}-{1:00}-{2:00} @ {3:00}:{4:00} (system time)", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute));
|
|
if (_Client.Interface != null)
|
|
sw.WriteLine(string.Format("Interface : {0}", _Client.Interface.ToString()));
|
|
else
|
|
sw.WriteLine("Interface : null");
|
|
sw.WriteLine(string.Format("Profile : {0}", _Profile.Title));
|
|
sw.WriteLine("");
|
|
sw.WriteLine("Timestamp; Command; Returndata");
|
|
}
|
|
_Client.DataTransferLogFile = _DataTransferLogFile;
|
|
}
|
|
catch { _Client.DataTransferLogFile = null; }
|
|
}
|
|
|
|
|
|
|
|
private void InitEventLog()
|
|
{
|
|
try
|
|
{
|
|
_EventLogs = new List<string>();
|
|
|
|
DateTime dt = DateTime.Now;
|
|
_EventLogFile = _LogFilePath + "\\" + string.Format("Task_{0:00000}_{1:0000}{2:00}{3:00}.{4:00}{5:00}{6:00}_events.csv", _Client.MIDS, dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
|
|
|
|
using (StreamWriter sw = File.CreateText(_EventLogFile))
|
|
{
|
|
sw.WriteLine(string.Format("Client : {0}", _Client.ToString()));
|
|
sw.WriteLine(string.Format("Created : {0:0000}-{1:00}-{2:00} @ {3:00}:{4:00} (system time)", dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute));
|
|
if (_Client.Interface != null)
|
|
sw.WriteLine(string.Format("Interface : {0}", _Client.Interface.ToString()));
|
|
else
|
|
sw.WriteLine("Interface : null");
|
|
sw.WriteLine(string.Format("Profile : {0}", _Profile.Title));
|
|
sw.WriteLine("");
|
|
}
|
|
}
|
|
catch { _EventLogFile = null; }
|
|
}
|
|
|
|
|
|
|
|
public String Description
|
|
{
|
|
get
|
|
{
|
|
string result = string.Format("{0:00000} : Profile '{1}'", _Client.MIDS, _Profile.Title);
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
List<String> _EventLogs; public List<String> EventLogs { get { return _EventLogs; } }
|
|
protected void AddEventLog(String message)
|
|
{
|
|
try
|
|
{
|
|
DateTime d = DateTime.Now;
|
|
string sTimestamp = String.Format("{0:0000}-{1:00}-{2:00} @ {3:00}:{4:00}:{5:00}", d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second);
|
|
string entry = String.Format("{0} : {1}", sTimestamp, message);
|
|
//if (_EventLogs.Count > 10000) // Prevent overflowing the list
|
|
//_EventLogs.RemoveAt(0);
|
|
|
|
_EventLogs.Add(entry);
|
|
|
|
if (_EventLogFile != null)
|
|
{
|
|
using (System.IO.StreamWriter sw = System.IO.File.AppendText(_EventLogFile))
|
|
{
|
|
sw.WriteLine(entry);
|
|
}
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public DateTime StartOfTask { get { return _startThread; } }
|
|
public Boolean IsRunningStandAlone { get { return _IsRunningStandAlone; } }
|
|
public Profile Profile { get { return _Profile; } }
|
|
public TaskStatus Status { get { return _Status; } }
|
|
|
|
|
|
public virtual Boolean IsStandAloneProgrammable(Profile profile)
|
|
{
|
|
return _Client.IsProgrammable(profile);
|
|
}
|
|
|
|
public abstract Boolean IsControlledProgrammable(Profile profile);
|
|
|
|
public String TaskProgress { get { return _TaskProgress; } }
|
|
|
|
public Boolean Start(Boolean isStandAlone)
|
|
{
|
|
if (_Status != TaskStatus.IsRunning)
|
|
{
|
|
InitDataTransferLog(); // Only init if also really started
|
|
InitEventLog();
|
|
|
|
_Status = TaskStatus.IsRunning;
|
|
|
|
if (isStandAlone)
|
|
{
|
|
_thread = new Thread(new ThreadStart(ThreadStandAlone));
|
|
}
|
|
else
|
|
{
|
|
_thread = new Thread(new ThreadStart(ThreadControlled));
|
|
}
|
|
_thread.Start();
|
|
_startThread = DateTime.Now;
|
|
_IsRunningStandAlone = isStandAlone;
|
|
|
|
if(isStandAlone)
|
|
AddEventLog("Stand alone task started");
|
|
else
|
|
AddEventLog("Controlled task started");
|
|
|
|
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public Boolean Stop()
|
|
{
|
|
_Status = TaskStatus.AbortRequested;
|
|
|
|
DateTime OnStop = DateTime.Now;
|
|
|
|
while ((_isKicking) && (OnStop.AddSeconds(20) > DateTime.Now))
|
|
Thread.Sleep(100);
|
|
|
|
if (_isKicking)
|
|
{
|
|
_thread.Abort();
|
|
Thread.Sleep(100);
|
|
if (_thread.Join(2000))
|
|
_isKicking = false;
|
|
}
|
|
|
|
if (!_isKicking)
|
|
_Status = TaskStatus.Finished; // Set to finished because user invoked
|
|
|
|
return !_isKicking;
|
|
}
|
|
|
|
|
|
public Boolean NextStep()
|
|
{
|
|
_Status = TaskStatus.NextStepRequested;
|
|
|
|
DateTime OnStop = DateTime.Now;
|
|
while (_Status == TaskStatus.NextStepRequested && (OnStop.AddSeconds(30) > DateTime.Now))
|
|
Thread.Sleep(200);
|
|
|
|
return (_Status == TaskStatus.IsRunning);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected String _TaskProgress;
|
|
protected Thread _thread;
|
|
protected Client _Client; public Client Client { get { return _Client; } }
|
|
protected DateTime _startThread;
|
|
protected Profile _Profile;
|
|
protected Boolean _isKicking;
|
|
protected TaskStatus _Status = TaskStatus.Starting;
|
|
protected abstract void ThreadControlled();
|
|
protected abstract void ThreadStandAlone();
|
|
protected Boolean _IsRunningStandAlone;
|
|
|
|
|
|
|
|
public Color StatusColor
|
|
{
|
|
get
|
|
{
|
|
Color color = Color.Black;
|
|
|
|
switch (_Status)
|
|
{
|
|
case TaskStatus.ExceptionOccured:
|
|
color = Color.Red;
|
|
break;
|
|
case TaskStatus.IsRunning:
|
|
color = Color.Green;
|
|
break;
|
|
case TaskStatus.Stopped:
|
|
color = Color.Orange;
|
|
break;
|
|
case TaskStatus.Finished:
|
|
color = Color.DarkGray;
|
|
break;
|
|
default:
|
|
color = Color.Black;
|
|
break;
|
|
}
|
|
return color;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public enum TaskStatus
|
|
{
|
|
Starting,
|
|
IsRunning,
|
|
AbortRequested,
|
|
Aborted,
|
|
Stopped,
|
|
Interrupted,
|
|
Finished,
|
|
ExceptionOccured,
|
|
NextStepRequested,
|
|
}
|
|
|
|
|
|
public static class TaskStatusExtensionMethods
|
|
{
|
|
public static string ToText(this TaskStatus s)
|
|
{
|
|
string result = s.ToString();
|
|
|
|
switch (s)
|
|
{
|
|
case TaskStatus.AbortRequested:
|
|
result = "Abort requested";
|
|
break;
|
|
case TaskStatus.ExceptionOccured:
|
|
result = "Exception occured";
|
|
break;
|
|
case TaskStatus.IsRunning:
|
|
result = "Running";
|
|
break;
|
|
case TaskStatus.NextStepRequested:
|
|
result = "Proceeding with next step";
|
|
break;
|
|
default:
|
|
result = s.ToString();
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|