##// END OF EJS Templates
Added Skip method to JSON parser to skip contents of the current node
Added Skip method to JSON parser to skip contents of the current node

File last commit:

r48:d9d794b61bb9 interactive logger
r62:62b440d46313 default
Show More
InteractiveListener.cs
122 lines | 3.8 KiB | text/x-csharp | CSharpLexer
cin
refactoring, interactive tarce log almost complete
r47 using Implab.Parallels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Implab.Diagnostics.Interactive
{
cin
Interactive tracing...
r48 public class InteractiveListener: TextListenerBase
cin
refactoring, interactive tarce log almost complete
r47 {
TraceForm m_form;
SynchronizationContext m_syncGuiThread;
cin
Interactive tracing...
r48 readonly Promise<object> m_guiStarted = new Promise<object>();
cin
refactoring, interactive tarce log almost complete
r47
readonly IPromiseBase m_guiFinished;
readonly IPromiseBase m_workerFinished = new Promise<object>();
readonly MTQueue<TraceViewItem> m_queue = new MTQueue<TraceViewItem>();
readonly AutoResetEvent m_queueEvent = new AutoResetEvent(false);
int m_queueLength;
bool m_exitPending;
readonly object m_pauseLock = new object();
bool m_paused;
readonly ManualResetEvent m_pauseEvent = new ManualResetEvent(true);
cin
Interactive tracing...
r48 public InteractiveListener(bool global) : base(global) {
m_guiFinished = AsyncPool.InvokeNewThread(GuiThread);
m_workerFinished = AsyncPool.InvokeNewThread(QueueThread);
cin
refactoring, interactive tarce log almost complete
r47
m_guiStarted.Join();
}
void GuiThread() {
m_form = new TraceForm(); // will create SynchronizationContext
cin
Interactive tracing...
r48
m_form.PauseEvents += (s,a) => Pause();
m_form.ResumeEvents += (s, a) => Resume();
cin
refactoring, interactive tarce log almost complete
r47 m_syncGuiThread = SynchronizationContext.Current;
m_guiStarted.Resolve();
Application.Run();
}
void QueueThread() {
while (!m_exitPending) {
if (m_paused)
m_pauseEvent.WaitOne();
TraceViewItem item;
if (m_queue.TryDequeue(out item)) {
Interlocked.Decrement(ref m_queueLength);
m_syncGuiThread.Send(x => m_form.AddTraceEvent(item),null);
} else {
m_queueEvent.WaitOne();
}
}
}
public void Pause() {
// for consistency we need to set this properties atomically
lock (m_pauseLock) {
m_pauseEvent.Reset();
m_paused = true;
}
}
public void Resume() {
// for consistency we need to set this properties atomically
lock (m_pauseLock) {
m_paused = false;
m_pauseEvent.Set();
}
}
void Enqueue(TraceViewItem item) {
m_queue.Enqueue(item);
if (Interlocked.Increment(ref m_queueLength) == 1)
m_queueEvent.Set();
}
public void ShowForm() {
m_syncGuiThread.Post(x => m_form.Show(), null);
}
public void HideForm() {
m_syncGuiThread.Post(x => m_form.Hide(), null);
}
void Terminate() {
cin
Interactive tracing...
r48 m_exitPending = true;
Resume();
cin
refactoring, interactive tarce log almost complete
r47 m_syncGuiThread.Post(x => Application.ExitThread(), null);
}
protected override void Dispose(bool disposing) {
if (disposing) {
Terminate();
m_guiFinished.Join();
}
base.Dispose(disposing);
}
cin
Interactive tracing...
r48
protected override void WriteEntry(TraceContext context, EventText text, string channel) {
var item = new TraceViewItem {
Indent = text.indent,
Message = text.content,
Thread = context.ThreadId,
Channel = channel,
Timestamp = Environment.TickCount
};
Enqueue(item);
}
cin
refactoring, interactive tarce log almost complete
r47 }
}