Here is the How To:
<StartAction>Program</StartAction>
<StartProgram>C:\DEV TOOLS\Program Files\NUnit 2.4.3\bin\nunit.exe</StartProgram>
Pressing F5 will launch NUnit now and start debugging.
Here is the How To:
<StartAction>Program</StartAction>
<StartProgram>C:\DEV TOOLS\Program Files\NUnit 2.4.3\bin\nunit.exe</StartProgram>
Pressing F5 will launch NUnit now and start debugging.
The Agenda...
I should say at this point that I am a dyed-in-the-wool Winforms developer although I have developed a fair few websites in my time. I've built web apps (mostly modestly sized affairs) using everything from Visual Interdev (remember that?), Notepad, and all .NET Visual Studio editions. I've done it but I have to say I don't like it. Why? If I'm brutally honest I hate the pace of development, the fact the tools aren't properly integrated and browsers that can't agree how to render anything useful; These are just my top 3 hates.
How wrong I was.
I had about 90% of the demo complete well within my initial estimate and then proceeded to put the breakpoint on the JavaScript code in the page and entered a world of pain. I use Firefox as my main browser and, naturally, VS 2008 JavaScript debugging doesn't work there. Okay, set IE 7 as my default browser for the web project, problem solved... well, no. Hmmm... Reboot? No. Repair install of Visual Studio? No. Another reboot? No. Go moan to someone else about how s@#t web development is? Worked like a charm.
Somebody please explain how bringing someone over to your PC and showing them how something doesn't work can suddenly kick it into life. I say this, but it didn't work the *first* time, just the second and every time since.
Its things like this that give me killer headaches and make me want to go back to the nice cosy world of framework development...
Aside from a nice preview of the 'design' and the (admittedly) cool CSS stuff there aren't a lot of compelling reasons to spend a large wad of cash rather than just use notepad. I mean, if I'm going to get stressed and generally harassed by technology that isn't reliable, doesn't work and then magically cooperates I may as well start in the position of expecting things to be tough and just use everyone's favourite free web development tool.
PS I don’t really mean that we should be using notepad because it would be really frustrating. The issue is that Visual Studio 2008 is so close, but so frustratingly far from being a great web development environment.
PPS I love everything else about Visual Studio.
I thought I would just send this out as a reminder. While everyone is eager to do right by FxCop we should not forget to use the Invariant Culture where appropriate.
FxCop will complain about any string formatting without an explicit culture. If you are formatting for internal use and not for display you really should consider using CultureInfo.InvariantCulture. This is particularly important if you plan to consume the string with software. Using the current culture would mean the string potentially could not be consumed by another server/PC. For example, if you used BCMax in Dubai it would have a different culture to the StrataMax server running here.
So if it is an internal string not for display or to be interpreted by software anywhere consider doing this:
receiptNumber.ToString("#", CultureInfo.InvariantCulture);
receiptNumber.ToString(CultureInfo.CurrentCulture);
Dorian, our CIO, has been busily hammering the VB.NET based shopping cart selected for a large client into shape.
Anthem.NET is a free, cross-browser AJAX toolkit for the ASP.NET development environment that works with both ASP.NET 1.1 and 2.0. http://anthem-dot-net.sourceforge.net/
Please ignore lack of indenting ... blogger keeps eating my directives. Kent Bolton
Before Anthem it was enough to put an error handler in the Global.asax on the Application_Error event to log the error and use the
In Anthem it is possible to have Ajax call backs to the web page, controls or even custom methods decorated. Exceptions could be raised on the methods called or even on methods not directly called by these methods such as load events for controls that Anthem causes to load dynamically.
Private Sub Page_Error(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Error
Response.Redirect("http://somewhere/")
End Sub
In order to avoid putting this method on every page it must be placed on the base page class for the entire website. There is a small downside to this which is a page can no longer define its own Page_Error method because control would be lost in the event execution chain when a Response.Redirect is started (it aborts the thread). This is however a necessary evil as there doesn’t seem to be another way to catch Anthem exceptions.
Protected Sub btnNext_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs) Handles btnNext.Click
SomeHiddenPanel.Visible = True
Anthem.Manager.AddScriptForClientSideEval("if (typeof document.someform != ""undefined"") { documentsomeform.submit(); }")
End Sub
' This will turn off the cache for the above locations
currentPage.Response.Cache.SetCacheability (Web.HttpCacheability.NoCache)
currentPage.Response.Cache.SetNoStore()
currentPage.Response.Cache.SetExpires (DateTime.Now().AddDays(-366))
currentPage.Response.Cache.SetMaxAge (New TimeSpan(0))
currentPage.Response.Cache.AppendCacheExtension ("must-revalidate, proxy-revalidate")
' This is to explicitly add to header to avoid being cached in the client browser, without the above code the page might still be cached on the server but just not in the client. For example cache is set to Server and the following codes are also added
Dim Expires As New Web.UI.HtmlControls.HtmlMeta()
Expires.Name = "Expires"
Expires.Content = "0"
currentPage.Header.Controls.Add(Expires)
Dim CacheControl As New Web.UI.HtmlControls.HtmlMeta()
CacheControl.Name = "Cache-Control"
CacheControl.Content = "no-cache"
currentPage.Header.Controls.Add(CacheControl)
Pragma.Name = "Pragma"
Pragma.Content = "no-cache"
currentPage.Header.Controls.Add(Pragma)
End Sub
The purpose of ABCD is to send and receive data over the internet. It is a command driven program, with an interface similar to FTP. After testing its responses, it became apparent that it was unreliable. Not only could it return errors about failing to connect to its server, but also logon failure and timeouts. In addition, there were some more obscure, but regular, failures – corrupted stream and handshake failure. There was no way to predict these failures, but trying again immediately almost always worked.
The requirements for my program included executing ABCD many times each day, starting at 1am and finishing at 7pm. If it did not work, immediate action needed to be taken. At MaxSoft, we have a library that handles sending the SMS, so sending the message was not a problem. However, since the SMS was to our CIO, it was important to identify the problem and attempt to rectify it first.
ABCD does not return an error code. It does not log its results to a database, or a file. The only way it notifies its results is directly to the screen. In addition, when it downloads files as a batch, the batch can contain multiple files of the same name. The first file gets overwritten by the second file with the same name. This meant that I could not pipe the standard output of ABCD to a file and interpret it after it had executed – some files would have been lost by then.
The answer was to use some of the features of System.Diagnostics.Process. This class allows for the Standard Output (which normally is displayed on the screen) to be captured as it occurs. It also allows for Standard Error to be captured, and for Standard Input to be written to. I passed the commands to ABCD by writing to the StandardInput stream, allowing me to protect the user id and password.
I then set Process.EnableRaisingEvent to true and called Process.BeginOutputReadLine. This activates the OutputDataReceived event, which I set to call my OutputDataReceived function.
I set up an array of strings for the expected result. The output was the same all the time, except the list of files produced, which I added as a place-holder string to the expected result. Each time OutputDataReceived was called, I compared the text that had been added to StandardOutput to the next item in the expected results. If it matched, I removed that section from the expected results and exited the OutputDataReceived function. If it did not match, I recorded the error and exited the function. When Process.WaitForExit completes, this error information is checked to determine if the process has run correctly or not. The placeholder string is used to identify when the list of files is being processed. This is only removed from the expected result when the following expected result is received.
Having written this, I was getting all errors reported. I wanted to reduce the calls our CIO received early in the morning (So did he), so I processed the error message. If any of the three errors that could be retried occurred, I looped back to where ABCD was being set up and ran it again. Along with providing the maximum number of retries, this eliminated alerts being generated on transient errors. If any other error occurred, ABCD was not rerun, and the alert was sent straight away.
Issues that I had resolved include:
- calling a console application using System.Diagnostics.Process
Process p = new Process();
ProcessStartInfo si = new ProcessStartInfo(application);
p.StartInfo = si;
si.Arguments = arguments;
si.UseShellExecute = false;
p.Start();
- retrieving and interpreting text output to the screen
si.RedirectStandardOutput = true;
p.EnableRaisingEvents = true;
p.OutputDataReceived += new DataReceivedEventHandler(OutputDataReceived);
p.BeginOutputReadLine();
- timeouts and other retryable errors
void OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data == null)
return;
// check e.Data for retryable errors and set flag indicating retry required
}
- preventing the console application for running forever by using WaitForExit with a time limit
if (!p.WaitForExit(Config.TimeoutSeconds * 1000))
{
p.Kill();
}
p.Close();
In the IT department here at MaxSoft, we hold fortnightly catchups with the guys. Since there are currently ten guys involved in these regular catchups with me, I have one scheduled every day of the week. We cover three main points religiously:
What have you done in the four hours a week we give you to develop your skills
What are your priorities and work issues
How are you going generally and what improvements can be made to your environment
We cover a lot of ground in these meetings. In a recent catch up, we covered the contrasts between other workplaces and the environment here. The discussion on other workplaces verged into toxic workplaces, and terrible management types.
I was reminded of a subject I had covered a few years ago, dragged out a book called “Mask of Sanity” by Hervey Cleckley. It is available as a free pdf download, and covers the pathological personality type. Get it from http://www.cassiopaea.org/cass/sanity_1.PdF
A summary covered at http://www.cassiopaea.com/cassiopaea/psychopath.htm describes this personality type as follows:
Imagine - if you can - not having a conscience, none at all, no feelings of guilt or remorse no matter what you do, no limiting sense of concern for the well-being of strangers, friends, or even family members. Imagine no struggles with shame, not a single one in your whole life, no matter what kind of selfish, lazy, harmful, or immoral action you had taken.
And pretend that the concept of responsibility is unknown to you, except as a burden others seem to accept without question, like gullible fools.
Now add to this strange fantasy the ability to conceal from other people that your psychological makeup is radically different from theirs. Since everyone simply assumes that conscience is universal among human beings, hiding the fact that you are conscience-free is nearly effortless.
You are not held back from any of your desires by guilt or shame, and you are never confronted by others for your cold-bloodedness. The ice water in your veins is so bizarre, so completely outside of their personal experience, that they seldom even guess at your condition.
Around 4%, or 1 in 25 people will have this personality defect. There are a lot of sociopaths in jail and just as many in senior management.
My original motivation for reading this tome was to try to fathom the behaviour of a colleague of mine while working in a large organisation. He was charming, fearless and ruthless, and his superiors loved him. He also seemed not to care an iota about anyone, nor about getting the job done. His actions included borrowing a subordinate's laptop to test a program he found on the web. The install process included disabling the corporate virus and malware protection suite and led to the first ever major outbreak of a virus at this company. When it was obvious that the forensics clearly pointed to his employee's laptop, he loudly and publicly led the charge to have him sacked, while privately telling the employee to sit tight. The employee was saved from dismissal by a divisional general manager who intervened. When the employee confided in me six months later, it was because his boss had neither thanked him nor apologised for his behaviour.
I'm sure most of you with a few years under the belt have had experiences with personality types you never, ever want to be involved with again. There are some that you'd especially go to great lengths to make sure that you never had to work for again.
What I am particularly interested in is how to use this feedback about the negatives of other workplaces into something that can be used positively.
The impact management, and especially the direct manager has on employees is massive. Any manager potentially can create an environment that is going to drive away not only your best and brightest, but your best and brightest in training. And you may never know about this until it is far too late.
If you care about care about getting great results for your business, the quality of the code your team produces, and the team itself, you need to provide an environment which not only stops your guys worrying about your reaction to situations, but also has them telling recruiters to stop calling for anything other than another dream job that pays twice as much.
Regular catch up sessions are a vital component to ensure that your guys are not only happy and productive, but also that you are not making them ticked off and distracted.
Some useful tips for these regular sessions:
Have a predictable agenda of open questions designed to open up conversation rather than confine it.
It is a two way street - your performance should be discussed as well.
Don't cancel these meetings too often – if they are run well, there's not many things that are more important.
Personalise the meeting to the needs of the employee. Take notes if you do not have a good memory.
Run well, these meetings should be able to nip potential problems in the bud, fine tune your department's priorities, improve your management style and also help you establish a quality relationship with the people you should value most in your company.
Even better, your annual or six monthly review process should be easy, painless and contain no big surprises.
By the way, we are currently looking to increase my regular catchup meeting workload by hiring more .NET engineers wanting to work in an environment that cares about employee development and producing great code.
If you are interested, e-mail me, Kent Bolton. I can be contacted via kbolton with an at sign here maxsoft.com.au. Please only apply if you are able to work on the gold coast in Australia, and have a serious passion for coding.