protected override void Run()
{
using (RecorderCallbackServiceAgent callbackAgent = new RecorderCallbackServiceAgent(_serverHostName, _serverTcpPort))
{
try
{
SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS | EXECUTION_STATE.ES_SYSTEM_REQUIRED | EXECUTION_STATE.ES_AWAYMODE_REQUIRED);
if (this.StopTimeUtc <= DateTime.UtcNow || _startTimeUtc >= this.StopTimeUtc)
{
CallStartRecordingFailed(callbackAgent, String.Format(CultureInfo.InvariantCulture,
"Recording of {0} at {1} for {2} has invalid timing parameters.",
_channelAllocation.ChannelName, _startTimeUtc.ToLocalTime().ToShortTimeString(), this.StopTimeUtc.Subtract(_startTimeUtc)));
return;
}
if (_waitForThreadToComplete != null)
{
_waitForThreadToComplete.Join();
}
bool aborted = false;
_usedSuggestedBaseFileName = !_okToRenameRecordedFiles;
// First of all make sure the recorder is tuned to the correct channel.
string errorMessage = null;
if (!OnPrepareRecording(callbackAgent, ref errorMessage))
{
CallStartRecordingFailed(callbackAgent, errorMessage);
OnError();
aborted = true;
}
DateTime actualStartTimeUtc = DateTime.MaxValue;
if (!aborted)
{
// Now wait for the actual start-time
try
{
TimeSpan delay = _startTimeUtc.AddSeconds(-1) - DateTime.UtcNow;
if (delay.TotalMilliseconds > 0)
{
aborted = this.StopThreadEvent.WaitOne((int)delay.TotalMilliseconds, false);
}
if (!aborted)
{
errorMessage = null;
this.RecordingFileName = OnStartRecording(callbackAgent, ref errorMessage);
if (String.IsNullOrEmpty(this.RecordingFileName))
{
CallStartRecordingFailed(callbackAgent, errorMessage);
OnError();
aborted = true;
}
else
{
this.ActualRecordingFileName = ShareExplorer.TryConvertUncToLocal(this.RecordingFileName);
actualStartTimeUtc = DateTime.UtcNow;
CallAddNewRecording(callbackAgent, actualStartTimeUtc);
}
}
}
catch (Exception e)
{
CallStartRecordingFailed(callbackAgent, e.Message);
OnError();
aborted = true;
}
}
if (!aborted)
{
TimeSpan?checkerInterval = this.FileSizeCheckerInterval;
if (!checkerInterval.HasValue)
{
checkerInterval = TimeSpan.MaxValue;
}
_fileSizeChecker = new FileSizeChecker(this.ActualRecordingFileName, checkerInterval.Value);
while (!aborted && DateTime.UtcNow < this.StopTimeUtc)
{
TimeSpan interval = this.CheckRecordingActiveInterval;
TimeSpan timeToEnd = this.StopTimeUtc.AddMilliseconds(1) - DateTime.UtcNow;
if (timeToEnd < interval)
{
interval = timeToEnd;
}
aborted = this.StopThreadEvent.WaitOne(interval, false);
}
if (aborted)
{
WriteLog(TraceEventType.Warning, "RecordingThread [{0}]: Aborted", _recordingProgram.CreateProgramTitle());
}
if (!OnStopRecording(callbackAgent, aborted))
{
WriteLog(TraceEventType.Error, "RecordingThread [{0}]: Failed to stop recording", _recordingProgram.CreateProgramTitle());
try
{
callbackAgent.LogMessage(this.RecorderTunerId, LogSeverity.Error, "Failed to stop recording " + _recordingProgram.CreateProgramTitle());
}
catch { }
}
CallEndRecording(callbackAgent, actualStartTimeUtc, DateTime.UtcNow);
}
}
catch (Exception ex)
{
WriteLog(TraceEventType.Error, "RecordingThread [{0}]: {1}", _recordingProgram.CreateProgramTitle(), ex.Message);
try
{
callbackAgent.LogMessage(this.RecorderTunerId, LogSeverity.Error, "Exception: " + ex.Message);
}
catch { }
OnError();
}
finally
{
SetThreadExecutionState(EXECUTION_STATE.ES_CONTINUOUS);
}
}
OnThreadEnding();
}