How to profile a LINQPad query? - profiling

I want to determine where to optimize code in a LINQPad query. How can I do that?
Note that I'm not asking how to profile LINQ queries; just regular (C#) code in a LINQPad 'query' file (a regular LINQPad file).

I think the easiest is to write a Visual Studio console app. Barring that, I use a class I added to My Extensions - it is not terribly accurate in that it doesn't account for its own overhead well, but multiple loops through help:
using System.Runtime.CompilerServices;
public static class Profiler {
static int depth = 0;
static Dictionary<string, Stopwatch> SWs = new Dictionary<string, Stopwatch>();
static Dictionary<string, int> depths = new Dictionary<string, int>();
static Stack<string> names = new Stack<string>();
static List<string> nameOrder = new List<string>();
static Profiler() {
Init();
}
public static void Init() {
SWs.Clear();
names.Clear();
nameOrder.Clear();
depth = 0;
}
public static void Begin(string name = "",
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0) {
name += $" ({Path.GetFileName(sourceFilePath)}: {memberName}#{sourceLineNumber})";
names.Push(name);
if (!SWs.ContainsKey(name)) {
SWs[name] = new Stopwatch();
depths[name] = depth;
nameOrder.Add(name);
}
SWs[name].Start();
++depth;
}
public static void End() {
var name = names.Pop();
SWs[name].Stop();
--depth;
}
public static void EndBegin(string name = "",
[CallerMemberName] string memberName = "",
[CallerFilePath] string sourceFilePath = "",
[CallerLineNumber] int sourceLineNumber = 0) {
End();
Begin(name, memberName, sourceFilePath, sourceLineNumber);
}
public static void Dump() {
nameOrder.Select((name, i) => new {
Key = (new String('\t', depths[name])) + name,
Value = SWs[name].Elapsed
}).Dump("Profile");
}
}

Related

How to unit test a repository and mock db with moq

I am onboarding alone on an existing project that do not have any unit test. My first goal before any refactoring is to cover 100% of the code. I would like to avoid any regression.
I have read how do I mock sqlconnection or should I refactor the code? but my case as you can see below is quite different cause I need to do more than stub simply the sqlConnection. Basically, I need to mock the db. I would like to know the best approach to achieve it.
(By the way, I do not want to use any ORM such as Entity).
Below the code of the repository :
public class HotelRepository : IHotelRepository
{
private readonly IDbConnection _dbConnection;
private readonly ILogService _loggerService;
public HotelRepository(IDbConnection dbConnection, ILogService loggerService)
{
_dbConnection = dbConnection;
_loggerService = loggerService;
}
public HotelDo GetByRid(string rid)
{
return Find(rid).FirstOrDefault();
}
public List<HotelDo> Find(string text)
{
try
{
_dbConnection.Open();
var items = new List<HotelDo>();
using (var command = _dbConnection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.HotelSearchByRidOrName";
command.Parameters.Add(new SqlParameter("#Text", text));
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
items.Add(new HotelDo()
{
Name = SqlExtension.ReaderToStringConverter(reader["Name"]),
Id = SqlExtension.ReaderToIntConverter(reader["Id"]),
Rid = SqlExtension.ReaderToStringConverter(reader["RIDHotel"]),
IdPms = SqlExtension.ReaderToNullableIntConverter(reader["IdPms"]),
LinkResaWeb = SqlExtension.ReaderToStringConverter(reader["LinkResaWeb"]),
LinkPms = SqlExtension.ReaderToStringConverter(reader["LinkPms"]),
IdBrand = SqlExtension.ReaderToNullableIntConverter(reader["IdBrand"]) ?? 0,
IsOnline = SqlExtension.ReaderToBoolConverter(reader["IsOnline"]) ?? false,
CodeCountry = SqlExtension.ReaderToStringConverter(reader["CodeCountry"])
});
}
}
}
return items;
}
catch (Exception e)
{
var errorMessage = $"HotelRepository Find, text {text} ";
_loggerService.Trace(LogSeverity.Error, errorMessage, e);
throw new DalException() { Source = errorMessage, };
}
finally
{
_dbConnection.Close();
}
}
public List<HotelDo> GetAll()
{
try
{
_dbConnection.Open();
var items = new List<HotelDo>();
using (var command = _dbConnection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.HotelGetAll";
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
bool.TryParse(reader["IsOnline"].ToString(), out var isOnline);
items.Add(new HotelDo()
{
Id = SqlExtension.ReaderToIntConverter(reader["Id"]),
Rid = SqlExtension.ReaderToStringConverter(reader["RIDHotel"]),
Name = SqlExtension.ReaderToStringConverter(reader["Name"]),
CodeCountry = SqlExtension.ReaderToStringConverter(reader["CodeCountry"]),
LinkPms = SqlExtension.ReaderToStringConverter(reader["LinkPms"]),
IdPms = SqlExtension.ReaderToNullableIntConverter(reader["IdPms"]),
IdBrand = SqlExtension.ReaderToNullableIntConverter(reader["IdBrand"]) ?? 0,
LinkResaWeb = SqlExtension.ReaderToStringConverter(reader["LinkResaWeb"]),
IsOnline = isOnline
});
}
}
}
return items;
}
catch (Exception e)
{
var errorMessage = $"HotelRepository GetAllHotels";
_loggerService.Trace(LogSeverity.Error, errorMessage, e);
throw new DalException() { Source = errorMessage, };
}
finally
{
_dbConnection.Close();
}
}
}
Thank you for your help
So based on what you've got I've set up a test frame for you to follow. I've removed less important components for breviety.
Before you you jump in I just want to give my 2 cents, if you don't know how to do this sort of thing you seem to be more or less in a junior position or less experiance with C# and also found your self in a more or less mature company that doesn't care about the development deparment, since an uncovered project just get's thrown your way says you don't have alot of resources to go about to imrpove the code base.
Test only the things that have business value (can you put a price on the piece of logic if it brakes)
Delivering stuff faster will make you look better as a programmer (noone in the business gives a damn about test covarage)
Study hard, get your experiance, good reputation and don't be afraid to get the hell out of there as soon as you start getting bored.
Main
void Main()
{
var idIndex = 0;
var ids = new string[] { "1", "2" };
var mockDataReader = new Mock<IDataReader>();
mockDataReader.SetupSequence(x => x.Read()).Returns(true).Returns(true).Returns(false);
mockDataReader.SetupGet(x => x["Id"]).Returns(() => ids[idIndex]).Callback(() => idIndex++);
var mockParameters = new Mock<IDataParameterCollection>();
var mockCommand = new Mock<IDbCommand>();
mockCommand.SetupGet(x => x.Parameters).Returns(mockParameters.Object);
mockCommand.Setup(x => x.ExecuteReader(CommandBehavior.CloseConnection)).Returns(mockDataReader.Object);
var mockConnection = new Mock<IDbConnection>();
mockConnection.Setup(x => x.CreateCommand()).Returns(mockCommand.Object);
var repo = new HotelRepository(mockConnection.Object);
var result = repo.Find("search");
Assert.Equal("1", result[0].Id);
Assert.Equal("2", result[1].Id);
}
Repository
public class HotelRepository
{
private readonly IDbConnection _dbConnection;
public HotelRepository(IDbConnection dbConnection)
{
_dbConnection = dbConnection;
}
public List<Pony> Find(string text)
{
_dbConnection.Open();
var items = new List<Pony>();
using (var command = _dbConnection.CreateCommand())
{
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "dbo.HotelSearchByRidOrName";
command.Parameters.Add(new SqlParameter("#Text", text));
using (var reader = command.ExecuteReader(CommandBehavior.CloseConnection))
{
while (reader.Read())
{
items.Add(new Pony
{
Id = reader["Id"].ToString()
});
}
}
}
return items;
}
}
Just a dumb o'l pony
public class Pony {
public string Id { get; set; }
}

Reading objects from webservice actionscript

I need to read objects and save them in array. I did that on c# but can't figure out how to do that on actionscript.
c# example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TestingWSDLLOad.ServiceReference2;
namespace TestingWSDLLOad
{
class Program
{
static void Main(string[] args)
{
ServiceReference2.Service1Client testas = new ServiceReference2.Service1Client();
SortedList<int, PlayListItem> playList = new SortedList<int, PlayListItem>();
int cc = 0;
foreach (var resultas in testas.GetPlayList(394570))
{
PlayListItem ss = new PlayListItem(resultas.Id, resultas.VideoId, resultas.Path);
playList.Add(cc, ss);
cc++;
}
Console.WriteLine(playList[0].Id);
Console.ReadKey();
}
}
public class PlayListItem
{
public int VideoId { get; private set; }
public string Path { get; private set; }
public int Id { get; private set; }
public PlayListItem(int id, int videoId, string path)
{
Id = id;
VideoId = videoId;
Path = path;
}
}
}
I know how to get a simple result from wsdl using actionscript, but don't know how to get objects with parameteres and save them.
Service has a method GetPlaylist(int value) which returns an array of objects (id, videoId, path). How to handle this and save them ?
Here is my as3:
package {
public class data extends CasparTemplate {
var flvControl:FLVPlayback;
var refreshTimer:Timer;
var videoList:Array;
var videoNew:Array;
var videoMaxIds:Array;
var videoNewMaxIds:Array;
var videoIndex:uint;
var videoIdFrom:uint;
var loopAtEnd:Boolean;
var _playListItems:Array;
var _playList:PlayListItem;
var gotNewPlaylist:Boolean;
var webService:WebService;
var serviceOperation:AbstractOperation;
public function data()
{
_playListItems = new Array();
flvControl = new FLVPlayback();
videoNew = new Array();
videoNewMaxIds = new Array();
videoIndex = 0;
videoIdFrom = videoMaxIds[videoIndex];
loopAtEnd = true;
gotNewPlaylist = false;
refreshTimer = new Timer(20000);
refreshTimer.addEventListener(TimerEvent.TIMER, getNewPlaylist);
refreshTimer.start();
flvControl.addEventListener(VideoEvent.COMPLETE, completeHandler);
flvControl.addEventListener(VideoEvent.STATE_CHANGE, vidState);
flvControl.setSize(720, 576);
flvControl.visible = true;
//addChild(flvControl);
var url:String = "http://xxx/yyy.svc?wsdl";
webService = new WebService();
webService.loadWSDL(url);
webService.addEventListener(LoadEvent.LOAD, BuildServiceRequest);
}
function BuildServiceRequest(evt:LoadEvent):void
{
webService.removeEventListener(LoadEvent.LOAD, BuildServiceRequest);
//serviceOperation.addEventListener(ResultEvent.RESULT, displayResult);
for (var resultas in webService.getOperation("GetPlaylist(394575)"))
{
trace(resultas.Id);
}
//serviceOperation = webService.getOperation("GetPlaylist");
//serviceOperation.arguments[{videoId: "394575"}];
}
private function displayResult(e:ResultEvent):void
{
trace("sss");
}
// Handle the video completion (load the next video)
function completeHandler(event:VideoEvent):void
{
if (gotNewPlaylist)
{
videoList = videoNew;
videoMaxIds = videoNewMaxIds;
videoNew = null;
videoNewMaxIds = null;
gotNewPlaylist = false;
videoIndex = 0;
} else
videoIndex++;
nextVideo();
}
private function vidState(e:VideoEvent):void {
var flvPlayer:FLVPlayback = e.currentTarget as FLVPlayback;
if (flvPlayer.state==VideoState.CONNECTION_ERROR) {
trace("FLVPlayer Connection Error! -> path : "+flvPlayer.source);
videoIndex++;
nextVideo();
} else if (flvPlayer.state==VideoState.DISCONNECTED) {
videoIndex++;
nextVideo();
}
}
function nextVideo():void
{
trace("Video List:"+videoList.toString());
if( videoIndex == videoList.length ){
if( loopAtEnd )
{
videoIndex = 0;
} else { return; }
}
flvControl.source = videoList[videoIndex];
if (videoIdFrom < videoMaxIds[videoIndex])
videoIdFrom = videoMaxIds[videoIndex];
trace(videoIdFrom);
}
}
}
internal class PlayListItem
{
private var _videoId:int;
private var _path:String;
private var _id:int;
public function get VideoId():int { return _videoId; }
public function get Path():String { return _path; }
public function get Id():int { return _id; }
public function set VideoId(setValue:int):void { _videoId = setValue };
public function set Path(setValue:String):void { _path = setValue };
public function set Id(setValue:int):void { _id = setValue };
public function PlayListItem(id:int, videoId:int, path:String)
{
_videoId = videoId;
_id = id;
_path = path;
}// end function
}
I think you were on the right track with your commented-out code. Be aware that the getOperation() will return an AbstractOperation, which in my mind is simply a pointer to the remote function. You can set arguments on the object, or simply pass the arguments when you call send(). I know some people have had issues with the argument property approach, so simply passing your arguments in the send function may be the smart way to go.
The following replace BuildServiceRequest and displayResult
private function BuildServiceRequest(evt:LoadEvent):void {
webService.removeEventListener(LoadEvent.LOAD, BuildServiceRequest);
serviceOperation.addEventListener(ResultEvent.RESULT, displayResult);
serviceOperation = webService.getOperation("GetPlaylist");
serviceOperation.send(394575);
}
private function displayResult(e:ResultEvent):void {
// Store the token as our array.
_playListItems = e.token;
var msg:String;
// Loop through the array
for each (var entry:Object in _playListItems) {
msg = "";
// For every key:value pair, compose a message to trace
for (var key:String in entry) {
msg += key + ":" + entry[key] + " ";
}
trace(msg);
}
}

Protobuf-net - list of objects with parent reference

I have a simple class with reference to parent object. All objects are in one list (even parent objects). Is it possible to keep references references after deserialization?
In my code I have something like this:
[ProtoContract]
public class ProtoItem
{
[ProtoMember(1)]
public int Value { get; set; }
[ProtoMember(2, AsReference = true)]
public ProtoItem BaseItem { get; set; }
}
And main looks like that:
static void Main()
{
var itemParent = new ProtoItem { Value = 1 };
var item2 = new ProtoItem { Value = 2, BaseItem = itemParent };
var item3 = new ProtoItem { Value = 3, BaseItem = itemParent };
var parentListToWrite = new List<ProtoItem> {itemParent, item2, item3};
const string file = "protofile.txt";
try { File.Delete(file); }
catch { };
using (var fs = File.OpenWrite(file)) { Serializer.Serialize(fs,
parentListToWrite); }
List<ProtoItem> readList;
using (var fs = File.OpenRead(file)) { readList =
Serializer.Deserialize<List<ProtoItem>>(fs); }
if (readList[0] == readList[2].BaseItem)
{
//how to make it equal?
}
if (readList[0] == readList[1].BaseItem)
{
//how to make it equal?
}
}
Is it possible to deserialize that if conditions works?
The protobuf specification doesn't have the notion of object identity. protobuf-net does (as an optionally enabled feature), but it doesn't currently work for list items directly, although I suspect it probably should. Since it would break the format, though, it would need explicit enabling if I fixed this.
But the following code works today - note that what I have done here is to wrap the top-level list items in a wrapper that just encapsulates the ProtoItem, but in doing so enables reference-tracking. Not ideal, but: it works.
using ProtoBuf;
using System.Collections.Generic;
using System.IO;
[ProtoContract(AsReferenceDefault=true)]
public class ProtoItem
{
[ProtoMember(1)]
public int Value { get; set; }
[ProtoMember(2)]
public ProtoItem BaseItem { get; set; }
}
[ProtoContract]
public class Wrapper
{
[ProtoMember(1, DataFormat = DataFormat.Group)]
public ProtoItem Item { get;set; }
public static implicit operator ProtoItem(Wrapper value)
{
return value == null ? null : value.Item;
}
public static implicit operator Wrapper(ProtoItem value)
{
return value == null ? null : new Wrapper { Item = value };
}
}
static class Program
{
static void Main()
{
var itemParent = new ProtoItem { Value = 1 };
var item2 = new ProtoItem { Value = 2, BaseItem = itemParent };
var item3 = new ProtoItem { Value = 3, BaseItem = itemParent };
var parentListToWrite = new List<Wrapper> { itemParent, item2, item3 };
const string file = "protofile.txt";
try
{ File.Delete(file); }
catch
{ };
using (var fs = File.OpenWrite(file))
{
Serializer.Serialize(fs,
parentListToWrite);
}
List<Wrapper> readList;
using (var fs = File.OpenRead(file))
{
readList = Serializer.Deserialize<List<Wrapper>>(fs);
}
if (readList[0].Item == readList[2].Item.BaseItem)
{
//how to make it equal?
System.Console.WriteLine("eq");
}
if (readList[0].Item == readList[1].Item.BaseItem)
{
//how to make it equal?
System.Console.WriteLine("eq");
}
}
}

Iron Python throws exception on testing environment

I'm having a code which runs Iron Python scripts on VS 2010. Every time a test completes I get an exception of type ObjectDisposedException, with the description: Cannot write to a closed TextWriter. I can't see the stack trace. I'm accessing the scripts via this wrapper:
public static class PythonWrapper
{
public static dynamic GetClient(string clientName, string clientType)
{
var file = string.Format(#"{0}\Python\webcore.eas", Directory.GetCurrentDirectory());
dynamic result = null;
var ipy = GetRuntime();
var engine = ipy.GetEngine("py");
ScriptScope clientScope = engine.CreateScope();
if(File.Exists(file))
{
clientScope.SetVariable("asm", Assembly.Load(ServiceManager.Get<FileEncryptionSevice>().Decrypt(file)));
string dllWrapper = string.Format("import clr\n" +
"clr.AddReference(asm)\n" +
"from Clients.{0} import {1}\n" +
"del clr", clientName, clientType);
var src = engine.CreateScriptSourceFromString(dllWrapper);
var compiled = src.Compile();
compiled.Execute(clientScope);
result = clientScope.GetVariable(clientType);
}
else
{
var scope = ipy.UseFile(string.Format(#"{0}\Python\Clients\{1}.py", Directory.GetCurrentDirectory(),clientName));
result = scope.GetVariable(clientType);
}
return result;
}
private static ScriptRuntime GetRuntime()
{
var result = Python.CreateRuntime();
var engine = Python.GetEngine(result);
var baseFolder = string.Format(#"{0}\Python\", Directory.GetCurrentDirectory());
engine.SetSearchPaths(new[] {
string.Format("{0}", baseFolder),
string.Format(#"{0}\Lib\", Directory.GetCurrentDirectory())
});
return result;
}
}
I guess I'm attempting to access a disposed object but none of the scripting objects is IDisposable. I've also tried calling ScriptRuntime.ShutDown at the end of each test, but it only has the test stuck.
Please help me.
Kind regards,
Izhar
Turns out it was a simple bug of setting an output stream for the iron python. The following code solved the error
private static void SetOutputStream(ScriptEngine engine)
{
ScriptScope sys = engine.GetSysModule();
sys.SetVariable("stdout", new PythonStreamWrapper(LogLevel.Debug));
sys.SetVariable("stderr", new PythonStreamWrapper(LogLevel.Debug));
}
public class PythonStreamWrapper
{
private readonly ILogger _logger = LoggerService.GetLogger("Obj.Gen");
private LogLevel _logLevel;
public PythonStreamWrapper(LogLevel logLevel)
{
_logLevel = logLevel;
}
public void write(string text)
{
if (text.Trim() == "") return;
_logger.Write(_logLevel, text);
}
public int softspace
{
get;
set;
}
}

How to create multiple list depending on data retrieved?

I am consuming a webservice for getting the data and i am success fully getting back the data
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{ String username = txtblock4.Text.Trim();
String hash = txtblock8.Text.Trim();
client.UploadStringAsync(new
Uri("http://www.picturelove.mobi/picturelove3/getmessages.php?loginType=N&email=" +
username + "&hash=" + hash), "Post");
client.UploadStringCompleted += new
UploadStringCompletedEventHandler(client_UploadStringCompleted);
}
I am parsing the xml response like below with two functions save message data and generate message data i am gettin the data in a list.
void client_UploadStringCompleted(object sender, UploadStringCompletedEventArgs e)
{
if (e.Error != null)
txtblock10.Text = e.Error.Message.Trim();
else
txtblock10.Text = e.Result.Trim();
String XmlString = txtblock10.Text.Trim();
using (XmlReader reader = XmlReader.Create(new StringReader(XmlString)))
{
while (reader.ReadToFollowing("all_messages"))
{
while (reader.Read())
{
try
{
reader.ReadToFollowing("id");
string id = reader.ReadElementContentAsString();
reader.MoveToAttribute("from");
string n_from = reader.ReadElementContentAsString();
reader.MoveToAttribute("to");
string n_to = reader.ReadElementContentAsString();
reader.MoveToAttribute("time");
string n_time = reader.ReadElementContentAsString();
reader.MoveToAttribute("sub");
string n_sub = reader.ReadElementContentAsString();
reader.MoveToAttribute("ct");
string n_ct = reader.ReadElementContentAsString();
reader.MoveToAttribute("txt");
string n_txt = reader.ReadElementContentAsString();
reader.MoveToAttribute("msg_image");
string n_image = reader.ReadElementContentAsString();
reader.MoveToAttribute("gender");
string n_gender = reader.ReadElementContentAsString();
reader.MoveToAttribute("name");
string n_name = reader.ReadElementContentAsString();
reader.MoveToAttribute("avatar");
string n_avatar = reader.ReadElementContentAsString();
ObservableCollection<SampleData> dataSource = new ObservableCollection<SampleData>();
dataSource.Add(new SampleData() { Name = txtblock11.Text, Text = txtblock12.Text,
Time= txtblock13.Text, Picture = txtblock9.Text });
// listBox.Items.Add(new SampleData() { Name = txtblock11.Text, Text = txtblock8.Text,
Time = txtblock5.Text, Picture = txtblock12.Text });
SaveMessageData(new SampleData() { Name = txtblock11.Text, Text = txtblock12.Text, Time
= txtblock13.Text, Picture = txtblock9.Text });
// listBox1.ItemsSource =
this.GenerateMessageData();
}
catch
{
//MessageBox.Show("No New Messages For You", "No Message", MessageBoxButton.OK);
break;
}
}
}
}
}
}
public class SampleData
{
public string Name { get; set; }
public string Text { get; set; }
public string Time { get; set; }
public string Picture { get; set; }
}
public void SaveMessageData()
{
using (var isoStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var isoStream = new IsolatedStorageFileStream("MyTextfile.txt", FileMode.Append,
isoStorage))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<SampleData>));
using (XmlWriter xmlWriter = XmlWriter.Create(stream, xmlWriterSettings))
{
List<SampleData> data = new List<SampleData>();
foreach (SampleData obj in Listbox.Items)
{
data.Add(obj);
}
data.Add(msg);
if (data != null)
serializer.Serialize(xmlWriter, data);
}
}
}
}
}
public void GenerateMessageData()
{
List<SampleData> data;// = new List<SampleData>();
try
{
using (IsolatedStorageFile myIsolatedStorage =
IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile("MyTextfile.txt",
FileMode.Open))
{
XmlSerializer serializer = new XmlSerializer(typeof(List<SampleData>));
data = (List<SampleData>)serializer.Deserialize(stream);
this.Listbox.ItemsSource = data;
return data;
}
}
}
catch (Exception exp)
{
MessageBox.Show("No New Messages For You", "No Message", MessageBoxButton.OK);
}
return null;
}
But, The real problem is if there are two set of data(two messages) if i'm getting both are showing in the same list. How to manipulate or iterate multiple lists if there are multiple data?
If you need to merge two lists and there may be items which exist in both but you only want to appear in the merged list once, the easiest solution is to simply check if it's already in the list before adding it.