#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

192 lines
5.8 KiB

// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Diagnostics;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.Profiler.AddIn.Dialogs;
using ICSharpCode.Profiler.AddIn.OptionPanels;
using ICSharpCode.Profiler.Controller.Data;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
namespace ICSharpCode.Profiler.AddIn
{
/// <summary>
/// Description of ProfilerRunner.
/// </summary>
public class ProfilerRunner : IDisposable
{
public event EventHandler RunFinished;
ProfilerControlWindow controlWindow;
protected virtual void OnRunFinished(EventArgs e)
{
if (RunFinished != null) {
RunFinished(this, e);
}
}
Controller.Profiler profiler;
IProfilingDataWriter writer;
TempFileDatabase database;
public ICSharpCode.Profiler.Controller.Profiler Profiler {
get { return profiler; }
}
/// <summary>
/// Creates a new ProfilerRunner using a ProcessStartInfo and a data writer.
/// </summary>
public ProfilerRunner(ProcessStartInfo startInfo, bool useTempFileDatabase, IProfilingDataWriter writer)
{
if (writer == null)
throw new ArgumentNullException("writer");
if (startInfo == null)
throw new ArgumentNullException("startInfo");
if (useTempFileDatabase) {
this.database = new TempFileDatabase();
this.writer = writer;
this.profiler = new Controller.Profiler(startInfo, this.database.GetWriter(), OptionWrapper.CreateProfilerOptions());
} else {
this.database = null;
this.writer = writer;
this.profiler = new Controller.Profiler(startInfo, writer, OptionWrapper.CreateProfilerOptions());
}
PrintProfilerOptions();
this.profiler.RegisterFailed += delegate { MessageService.ShowError("${res:AddIns.Profiler.Messages.RegisterFailed}"); };
this.profiler.DeregisterFailed += delegate { MessageService.ShowError("${res:AddIns.Profiler.Messages.UnregisterFailed}"); };
this.profiler.OutputUpdated += delegate { SetOutputText(profiler.ProfilerOutput); };
this.profiler.SessionEnded += delegate { FinishSession(); };
}
void PrintProfilerOptions()
{
var options = OptionWrapper.CreateProfilerOptions();
LoggingService.Info("Profiler settings:");
LoggingService.Info("Shared memory size: " + options.SharedMemorySize + " (" + (options.SharedMemorySize / 1024 / 1024) + " MB)");
LoggingService.Info("Combine recursive calls: " + options.CombineRecursiveFunction);
LoggingService.Info("Enable DC: " + options.EnableDC);
LoggingService.Info("Profile .NET internals: " + (!options.DoNotProfileDotNetInternals));
LoggingService.Info("Track events: " + options.TrackEvents);
}
void FinishSession()
{
try {
using (AsynchronousWaitDialog dlg = AsynchronousWaitDialog.ShowWaitDialog(StringParser.Parse("${res:AddIns.Profiler.Messages.PreparingForAnalysis}"), true)) {
profiler.Dispose();
SD.MainThread.InvokeAsyncAndForget(() => { controlWindow.AllowClose = true; controlWindow.Close(); });
if (database != null) {
database.WriteTo(writer, progress => {
dlg.Progress = progress;
return !dlg.CancellationToken.IsCancellationRequested;
});
writer.Close();
database.Close();
} else {
writer.Close();
}
if (!dlg.CancellationToken.IsCancellationRequested)
OnRunFinished(EventArgs.Empty);
}
} catch (Exception ex) {
MessageService.ShowException(ex);
}
}
public Process Run()
{
SD.Workbench.GetPad(typeof(CompilerMessageView)).BringPadToFront();
controlWindow = new ProfilerControlWindow(this);
Process p = profiler.Start();
controlWindow.Show();
return p;
}
public void Stop()
{
profiler.Stop();
}
public static ProfilerRunner CreateRunner(IProfilingDataWriter writer)
{
AbstractProject currentProj = ProjectService.CurrentProject as AbstractProject;
if (currentProj == null)
return null;
if (!currentProj.IsStartable) {
if (MessageService.AskQuestion("${res:AddIns.Profiler.Messages.NoStartableProjectWantToProfileStartupProject}")) {
currentProj = ProjectService.OpenSolution.StartupProject as AbstractProject;
if (currentProj == null) {
MessageService.ShowError("${res:AddIns.Profiler.Messages.NoStartableProjectFound}");
return null;
}
} else
return null;
}
if (!File.Exists(currentProj.OutputAssemblyFullPath)) {
MessageService.ShowError("${res:AddIns.Profiler.Messages.FileNotFound}");
return null;
}
ProcessStartInfo startInfo;
try {
startInfo = currentProj.CreateStartInfo();
} catch (ProjectStartException ex) {
MessageService.ShowError(ex.Message);
return null;
}
ProfilerRunner runner = new ProfilerRunner(startInfo, true, writer);
return runner;
}
#region MessageView Management
static MessageViewCategory profileCategory;
static void EnsureProfileCategory()
{
if (profileCategory == null) {
MessageViewCategory.Create(ref profileCategory, "Profile", StringParser.Parse("${res:AddIns.Profiler.MessageViewCategory}"));
}
}
public static void SetOutputText(string text)
{
EnsureProfileCategory();
profileCategory.SetText(StringParser.Parse(text));
}
public static void AppendOutputText(string text)
{
EnsureProfileCategory();
profileCategory.AppendText(StringParser.Parse(text));
}
public static void AppendOutputLine(string text)
{
EnsureProfileCategory();
profileCategory.AppendLine(StringParser.Parse(text));
}
#endregion
bool isDisposed = false;
public void Dispose()
{
if (!isDisposed) {
profiler.Dispose();
controlWindow.Close();
isDisposed = true;
}
}
}
}