and has 0 comments
Petru Jucovschi was nice enough to invite me to a software development training organised by Microsoft and partly presented by him. The first of the two days of training was about the theory behind software development practices like agile development and CMMI, part presented by Victor Mihail from Trilex. The second was about the Team System Foundation Server and Visual Studio 2008 Team Edition integrating for a better software development practice.

Well, I am working on remembering everything that was said and done and I will make some longer posts that will describe at length what was presented.
As a short summary, I was familiar with a lot of the concepts from the first part, since I've done a little research into agile development in order to pass it on to my managers. The theory and principles behind Agile were detailed, then the major Agile methodologies were described, including eXtreme Programming, Scrum and (very shortly) MSF. Also concepts of Test Driven Development.
The second part was also partly known to me as I have seen another similar presentation at the previous RONUA meeting, but this time it lasted for 8 hours, so I had the opportunity to ask questions and see things done step by step. Basically, TFS is the tool that combines project management, business analysis, architecture, development, debugging and testing into a single useful bunch. The issue tracking is linked to reporting, integrated with Microsoft Project and Microsoft Excel and concepts like Continuous Integration are directly available along a better source control solution than Visual Source Safe. Bottom line, I can barely wait to start work in a rational, managed way.

Stay tuned for the details.

Well, someone asked me today about why his dynamically generated GridView throws a 'Object reference not set to an instance of an object.' exception at DataBind when he sets AllowPaging to true. I replicated the error and looked at the stack trace, it looked like this:
   at System.Web.UI.WebControls.GridView.BuildCallbackArgument(Int32 pageIndex)
at System.Web.UI.WebControls.GridView.CreateNumericPager(TableRow row, PagedDataSource pagedDataSource, Boolean addFirstLastPageButtons)
at System.Web.UI.WebControls.GridView.InitializePager(GridViewRow row, Int32 columnSpan, PagedDataSource pagedDataSource)
at System.Web.UI.WebControls.GridView.CreateRow(Int32 rowIndex, Int32 dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState, Boolean dataBind, Object dataItem, DataControlField[] fields, TableRowCollection rows, PagedDataSource pagedDataSource)
at System.Web.UI.WebControls.GridView.CreateChildControls(IEnumerable dataSource, Boolean dataBinding)
at System.Web.UI.WebControls.CompositeDataBoundControl.PerformDataBinding(IEnumerable data)
at System.Web.UI.WebControls.GridView.PerformDataBinding(IEnumerable data)
at System.Web.UI.WebControls.DataBoundControl.OnDataSourceViewSelectCallback(IEnumerable data)
at System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback)
at System.Web.UI.WebControls.DataBoundControl.PerformSelect()
at System.Web.UI.WebControls.BaseDataBoundControl.DataBind()
at System.Web.UI.WebControls.GridView.DataBind()
at Malaka.Page_Load(Object sender, EventArgs e) in c:\Inetpub\wwwroot\ScrollableFixedHeaderGrid\Malaka.aspx.cs:line 14
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)


So, the error occurs at the BuildCallbackArgument method in the GridView object. I used Lutz Roeder's Reflector to see the source of the GridView object and I got to this piece of code:
        private string BuildCallbackArgument(int pageIndex)
{
if (string.IsNullOrEmpty(this._sortExpressionSerialized))
{
this._sortExpressionSerialized = this.StateFormatter.Serialize(this.SortExpression);
}
return string.Concat(new object[] { "\"", pageIndex, "|", (int) this.SortDirection, "|", this._sortExpressionSerialized, "|\"" });
}


The error appears to be thrown by the StateFormatter property returning null. It's source is:
        private IStateFormatter StateFormatter
{
get
{
if (this._stateFormatter == null)
{
this._stateFormatter = this.Page.CreateStateFormatter();
}
return this._stateFormatter;
}
}


Got it? It assumes you already added the GridView to a Page. Well, this is the usual issue with the GridView.

Solution: Add the GridView to your Page (or to a fictive Page) and then DataBind it.

and has 0 comments
There are a lot of movies about aliens, creatures from another world, coming here for whatever reason and trying to communicate. They usually are well versed in English, but sometimes they use some other language like the Klingons or they snarl and rip you to pieces or, sometimes, have to find a protocol of communication first, by using mathematics, gestures or music (like in Close Encounters of the Third Kind). Yet none of those creatures astound me more than some of the people on Earth doing things I could never ever imagine doing and using it to communicate.

One of these people is Michael Moschen, who uses juggling as language of sorts in order to comunicate his perception of time, space and movement. You can watch a small demo he gave at TED and have your own say:



You can see that he uses separate elements to create, to build, larger ansembles. He uses juggling moves like a language, with structure and building blocks and architecture. Now, what would we do if aliens would want to talk to us by moving objects around and making sounds with their limbs? Would be build a computer that can be programmed by juggling? Would we immediately fly in Michael Moschen as the Earth ambassador? Or is it too science fiction to imagine alien creatures communicating in the same way some people do?

and has 0 comments
The level of satisfaction one gets from anything is inversely proportional with the level of expectation they have. I knew that in the RONUA meeting on the 9th there will be only two presentations, with subjects I can't use right now and with speakers I didn't exactly feel compelled to listen to. So, of course, I liked it!

But there was something more. Both speakers seemed more mature, more anchored on the subject than usual. It's not that Aurelian Popa did not seem overly arrogant or that the ever helpful Petru Jucovschi didn't have a lot more information than was humanly possible to present in the alloted time and resources, but their performance seemed way better than I was used to.

The subjects were pretty clear: WPF and VS TFS. If you are scared by acronyms you probably shouldn't be reading this :), but I did provide tooltips for them, so move the mouse over them.

The first presentation showed an ObservableCollection (new stuff from .Net 3.0 which allows notification on changing elements) containing SolarSystemItems, objects that encapsulated an image, a diameter, a name, an orbit and a temperature. It started from a simple listbox then, by changing only the presentation (Style) and the way data is presented (DataTemplate) in the XAML file, it gradually changed to a picture+details listbox, a combobox also with picture and everything, then with a details box next to it showing the current selected object, with filtering, sorting, grouping, etc. The grand finale was making the same listbox look like a solar system image, with selectable planets and the details on tooltip, with orbits and everything. The demo can be downloaded and seen at Beatriz Costa's blog.

The second presentation I was more interested in, since our company plans to use Visual Studio TFS to manage our work. Since that would mean a shift from the current Excel+Email+Messenger, I was glad to learn that the TFS learning curve is steep and usage can also start from source control only, moving ever so slightly towards a comprehensive development strategy, with testing, reporting, configurable XML files that describe any process (with out of the box or downloadable versions for MSF, Scrum, XP, CMMI) , etc.

I was surprised to see that not only the session was free, but we also received some gifts from Microsoft for attending. That included the MSDN subscription that I won, the WPF book that my colleague won, a kit with all kinds of goodies that I can't remember won by our boss and 40% discount for some Microsoft products for each. We cleaned house! No free food though :)

My conclusion was that the RONUA meetings are (as far as I have seen) the most techie, interesting and to the point Microsoft events. The MSDN briefings are nice, too, with more budget allocated to them and so on and so on, but they will never be able to replicate the sort of "gang of IT people" feel of the RONUA's meetings. And with people that are ever more implicated and interested in presenting, it can only get better.

and has 1 comment
Reading the BBC News today I've stumbled upon a fascinating article called "Great tits cope well with warming". Let me quote a little so you can understand what it is about: The research uses a long record of great tits in a breeding site at Wytham Woods near Oxford, where observations began in 1947. "We think it’s the longest running population study of wild animals anywhere in the world where animals are marked (ringed),"

So, warming doesn't negatively affect great tits! You can warm them yourselves or get someone else to do it. Isn't that wonderful? =))

Update 9 Sep 2009: Great tits found hunting bats for food

and has 0 comments
It started with web sites. They would put a small picture in the header of the site that on mouse over would fill the entire page with rubbish. We fixed it, usually, by using some utilities or by changing the ip of the offending ad to some non-sense ip.

Now they used the same ploy for Windows Live Messenger (formerly known as MSN). One could say that Microsoft doesn't need more money, but apparently they do. On YOUR expense! So, how can one get rid of the annoying flash ad at the bottom of MSN? Easy! Follow these steps (tested on version 8.5):
  1. Open folder Program Files\Windows Live\Messenger
  2. Copy file msgsres.dll to msgsres.dll.bak
  3. Find a text or hex editor that does not break a binary file on save (That means NO Notepad or Wordpad). Myself I used the text editor from FAR Manager, but there are tons of good freeware editors online. Just Google it.
  4. Open the msgsres.dll file with the text editor, look for
    <Element Id=Atom(AdBrowserCont) Layout=VerticalFlowLayout(0,0,3,0) Visible=false Padding=Rect(8,2,0,2)>
    and replace one letter from AdBrowserCont. I changed the A to an X, but it doesn't matter. What is important is not to change the length of the file; just replace, do not insert or delete anything.


That is all. The ad container will still appear and show the Windows Live Messenger window, but no ad will be loaded.

Of course, this is the do-it-yourself version. There is an utility that is largely recommended on the web to fix MSN, Windows Live Messenger and Yahoo Messenger ad issues, and that is A-patch, but I haven't tested it yet.

Thanks for Raheel for presenting me this problem and the opportunity to fix it.

As you may know from a previous post of mine, Ajax requests differ from normal requests. At the Page level, the rendered content is changed to reflect only the things that changed in the UpdatePanels and the format is different from the usual HTML and it is also very strict. Any attempt to blindly add things to the string sent from the server will result in an ugly alert error. And who does indiscriminately add ugly content to your Ajax requests? "Free" servers that inject commercials in your pages!

So, what can you do? Patch the Ajax engine to remove the offending ads. Here is a simple example for a server that added crap at THE END of the content, crap that did not contain any '|' characters. This is important, as the patch looks for the last '|' character and removes all the things after it.

C# Code

private void LoadApplyPatch()
{
ScriptManager sm = ScriptManager.GetCurrent(Page);
if (sm == null) return;

string script =@"
if (window.Sys&&Sys.WebForms&&Sys.WebForms.PageRequestManager) {
Sys$Net$WebRequestExecutor$get_responseData=function() {
if (arguments.length !== 0) throw Error.parameterCount();
if (!this._responseAvailable) {
throw Error.invalidOperation(String.format(Sys.Res.cannotCallBeforeResponse, 'get_responseData'));
}
if (!this._xmlHttpRequest) {
throw Error.invalidOperation(String.format(Sys.Res.cannotCallOutsideHandler, 'get_responseData'));
}

var content=this._xmlHttpRequest.responseText;

// this is the added code, the rest is taken
// from the ASP.Net Ajax original code
var index=content.lastIndexOf('|');
if (index<content.length-1)
content=content.substring(0,index+1);


return content;
}
}"
;

ScriptManager.RegisterStartupScript(Page,
Page.GetType(), "adMurderer", script, true);
}

and has 3 comments

Infected is a typical American sci-fi book, including small town mentality, a sports and US centric view, lots of government agencies, all working for the good of the citizens, keeping them all safe and ignorant and the warped morality that tells people they should destroy before they understand, just because they fear it.

That is something to be expected from an American author, though, and the book itself is not bad. It felt like it was inspired a lot by Stephen King's Dreamcatcher, which featured a similar personal dillema of alien infestation while the gov'ment was on the chase, but that one had more oompf. Of course, you can't compare aspiring Sigler to King, but then again, King's writing was never so great to me to begin with.

What I found really astounding is that a civilisation that uses biological machines to create a beach head on another planet would be so easily thwarted by a college athlete, a trigger happy black ops CIA agent and about a doctor and a half. Oh, and some Apache helicopters. What bothered me to no end is that I also felt this was a plausible scenario. I hope I am just stupidly influenced by similar literature, but would it really help to destroy the enemy before you get to at least understand it? What about the technology that was so easily recognisable as foreign and above Earth's current scientific level?

As a conclusion to both book and my own feelings: it was a nice read; not spectacular, but good enough to keep reading till the end. It is also available in podcast format and I myself have read it from a text file saved from a PDF that was gracefully provided free of charge by mr Sigler on the Escapepod podcast site.

Coma is one of my favourite bands if not THE favourite. They are Romanians, I know them, they're cool guys. Recently they organised an unpluggish concert called Coma Light. This is one of the songs there, although I do encourage you to look at them all (YouTube links gracefully provided by Imig/Smallex under the video). Great job, guys! Most of the songs you played deserve an album of their own. Here is the video for Culori, high quality from MetalHead TV. from YouTube.



Links to all the songs in the concert:
Stai
Mai presus de cuvinte
Bizz
Culori
In mine in soapta
Hectic
Un loc sa ajung
Daddy
Morphine
Coboara-ma-n rai
Cine iubeste si lasa
Canta-mi povestea

Update: I've posted the source and binaries for this control on Github. Free to use and change. Please comment on it.

This is the story of a control that shrinks the content sent from an UpdatePanel to down as 2% without using compression algorithms. I am willing to share the code with whoever wants it and I only ask in return to tell me if and where it went wrong so I can find a solution. Even if you are not interested in the control, the article describes a little about the inner workings of the ASP.Net Ajax mechanism.

You know the UpdatePanel, the control that updates its content asynchronously in ASP.Net, allowing you to easily transform a normal postback based application in a fully fledged Ajax app. Well, the only problem with that control is that you have to either put a lot of them on the page in order to update only what changes (making the site be also fast as you would expect from an Ajax application) but hard to maintain afterwards, or put a big UpdatePanel on the entire page (maybe in the MasterPage) and allow for large chunks of data to be passed back and forth and also other clear disadvantages, some detailed in this blog entry.

Not anymore! I have made a small class, in the form of a Response.Filter, that caches the previously rendered content and instructs the browser to do the same, then sends only a small fraction of the data from the server to the browser, mainly what has changed. There is still the issue of the speed it takes the browser to render the content, which is the same no matter what I do, like when rendering a huge table. It doesn't matter that I send only the changes in one cell, the browser must still render the huge grid. Also, if, for some reason, the update fails, I catch it and I send to the server that the updatepanel must be updated again, the old way.

Enough; let's talk code. I first had to tap into the content that was sent to the browser. That can only be done at Page render level (or PageAdapter, or Response.Filter and other things that can access the rendered content). So I did catch the rendered content in a filter, I recognized it as Ajax by its distinctive format, and I only processed the updatePanel type of token.

Here I had a few problems. First I replaced the updatePanel token with a scriptBlock token that changed the innerHTML of the update panel div element. It all seemed to work until I tested it a little. I discovered that the _updatePanel javascript method of the PageRequestManager object used by the normal ajax rendering on the browser was doing a few extra things, so I used that one instead of just replacing the innerHTML, resulting in a lower speed. But that didn't help either, because it failed when using validators. Even if I did replace the updatePanel token with a correct javascript block, it still got executed a bit later than it should have.

The only solution I had was to replace the _updatePanel method with my own. Itself having a small block of code that disposed some scriptblocks and some other stuff, then a plain innerHTML replace, I could not 'override' it, since it would change the innerHTML with some meaningless stuff (the thing I would send from the server), then I would parse and change the innerHTML again, resulting in bad performance, flickering, nonsense on screen, etc. So I just copy pasted the first part and added my own ApplyPatch function instead of the html replace code line.

Now, here I met another issue. The innerHTML property of an html element is not a simple string. It gets parsed immediately when set and it recreates when read, as explained in this previous article of mine. The only solution for that was create my own property of the update panel div element that remembers the string that was set. This solved a lot more problems, because it meant I could identify the content to be replaced by simple position markers rather than through regular expressions (as was my initial idea). That property would not get changed by custom local javascript either, so I was safe to use it.

About the regular expression engine in Javascript: it has no Singleline option. That means you can only change the content line by line. I could have used Steve Levithan's beautiful work, but with the solution found above, I would not need regular expressions at all.

The only other issue was with UpdatePanels inside UpdatePanels. I found out that in this case, only parent UpdatePanels are being rendered. That meant that the custom property I added to the child panel would disappear and break my code. Therefore I had to keep a tree of the updatepanels in the page and clear all the children cached content when the parents were being updated. So I did that, too.

What else? What if somehow the property would get deleted, changed, or something else happened, like someone decided to recreate the update panel div object or something like that? For that I made a little HttpHandler that would receive an UpdatePanel id and it would clear its cached content. Then, on return from the asynchronous call, the javascript would just push another update panel refresh using __doPostBack(updatePanelId,""). I don't particularily like this approach, since it could back fire with multiple UpdatePanels (as you know, only one postback at a time is supported), but I didn't find a better solution yet. Besides, this event should normally not happen.

So, the mechanism was all in place, all I had to do was make the actual patching mechanism, the one that would find the difference between previously rendered content and current content, then send only the changed part. First thing I did was remove the start and end of the strings that were identical. As you can imagine, that's the most common scenario: a change in the UpdatePanel means all the content up to the change remains unchanged and the same goes for the content after the change. But I was testing the filter with a large grid that would randomly change one cell to a random string. That meant two changes: the previous position and the last. Assuming the first change was in one of the starting cells and the last was in one of the cells at the end, then the compression would be meaningless. So I've googled for an algorithm that would give me the difference between two files/strings and I found Diff! Well, I knew about it so I actually googled for Diff :) It was in the Longest Common Substring algorithm category.

Anyway, the algorithm was nice, clear, explained, with code, perfect for what I wanted and completely useless, since it needed an array of m*n to get what I needed. It was slow, a complete memory hog and I couldn't possibly use an array of 500000x500000. I bet they were optimizations that covered this problem, but I was miserable so I just patched up my own messy algorithm. What would it do? It would randomly select a 100 characters long string from the current content and search for it in the previous content. If it found it, it would expand the selection and consider it a Reasonably Long Common Substring and work from then on recursively. If it didn't find it, it would search a few times other randomly chosen strings then give up. Well, actually is the same algorithm, made messy and with no extra memory requirements.

It worked far better than I had expected, even if it clearly could have used some optimizations. The code was clear enough in detriment of speed, but it still worked acceptably fast, with no noticeable overhead. After a few tweaks and fixes, the class was ready. I've tested it on a project we are working on, a big project, with some complex pages, it worked like a charm.

One particular page used a control I have made that allows for grid rows and columns to have children that can be shown/hidden at will. When collapsing a column (that means that every row gets some cells removed) the compressed size was still above 50% in up to 100 patch fragments. When colapsing a row, meaning some content from the middle of the grid would just vanish, the size went down to 2%! Of course, putting the ViewState into the session also helped. Gzip compression on the server would complement this nicely, shrinking the output even more.

So, I have demonstrated incredible compression of UpdatePanel content sent through the network with something as small and reusable as a response filter that can be added once in the master page. You could use it for customers that have network bandwidth issues or for sites that pay for sent out content. It would with sites made with one big UpdatePanel placed in the MasterPage as well :).

If you want to use it in your sites, please let me know how it performs and what problems you've encountered.

I have been working on an idea, one that assumed that if you remember the content sent to an UpdatePanel, you can send only the difference next time you update it. That would mean that you could use only one UpdatePanel, maybe in the MasterPage, and update only changes, wherever they'd be and no matter how small.

However, I also assumed that if I set the innerHTML property of an HTML element, the value will remain the same. In other words that elem.innerHTML=content; implied that elem.innerHTML and content are identical at the end of the operation. But they were not! Apparently the browser (each flavour in its own way) interprets the string that you feed it then creates the element tree structure. If you query the innerHTML property, it uses the node structure to recreate it.

So comparing the value that you've fed it to the actual value of innerHTML after the operation, you see quoted attribute values, altogether removed attributes when they have the default value, uppercased keywords, changed attribute order and so on and so on. FireFox only adds quotes as far as I see, but you never know what they'll do next.

On the bright side, now that my idea had been torn to shreds by the browser implementation, I now have an answer to all those stuck up web developers that consider innerHTML unclean or unstructured and criticize the browsers for not being able to render as fast when using DOM methods. The innerHTML property is like a web service. You feed it your changes in (almost) XML format and it applies it on the browser. Since you pretty much do the same when you use any form of web request, including Ajax, you cannot complain.

and has 0 comments
This is a little YouTube video that shows a photoshoot of Angelina Jolie's when she was a teen. As you will see, she is a lovely looking girl, but that is not the reason I am posting this in my blog. The reason is the feeling that I am having watching this: dread. Here is a 16 years old girl, faking all the emotions in all the pictures that are made of her, with an ice cool professionalism, chewing gum when the film is being changed in the camera. You can imagine what kind of pictures will result from this shoot, when all of this is probably filmed in a small humid room with people watching TV at its more stupidest. Can you imagine trying to concentrate with that noise around? If you ever thought Angelina got to where she is because of her looks only, think again. This little human robot has good programming.


Angelina Jolie - Bikini modeling from 1992 (Photoshoot)

Update: On June 20th 2009, Codeplex notified me that the patch I did for the ACT has been applied. I haven't tested it yet, though. Get the latest source (not latest stable version) and you should be fine.

The Ajax Control Toolkit has a PopupExtender module that is used throughout the library in whichever controls need to show above other controls. I wanted to use the Calendar Extender in my web site, but the calendar appeared underneath other controls. I checked it out and it had a zIndex of 1000, which should have been enough. I took me an hour to realise that in the toolkit code zIndex was a property of the div element, not of the div style!

A download of the latest version from Feb 29 shows the problem is still there. The fix? go to the PopupExtender folder in the source code, open the PopupBehaviour.js file, search for a line that looks like this:
element.zIndex = 1000;
and replace it with
element.style.zIndex = 1000;
. Now it works!

The issue is already in the AjaxControlToolKit issue tracker, but it was not addressed yet.

and has 0 comments
No, you are not mistaken, the voice for this band is Juliette Lewis herself, a pretty known actress that usually interprets beautifully screwed up characters. No wonder her music is similar :) But when I first heard of the band I didn't even bother to listen to them. Not another acting celebrity trying to sing! But when I found out the vocal on Prodigy's Spitfire and Hot Ride songs was Juliette Lewis, I changed my mind. And I am glad I did. Here is the weird and nicely sung Hot Kiss.



Licks:
MySpace page for Juliette & the Licks
Wikipedia entry
Juliette & the Licks fan site

A little used thingie on the SqlConnection object called the InfoMessage event fires whenever there were info messages (duh!) from the last query or stored procedure execution. That means errors, of course, but it also means warnings and simple prints! You get where I am going with this?

Instead of changing stored procedures, datalayers and code whenever I need to get some new information from SQL, I can just add some nicely formatted PRINT commands and get all the information I need! Here is some code:

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Windows.Forms;

namespace SqlPrintCommands
{
public partial class Form2 : Form
{
public Dictionary<string, string> values;

public Form2()
{
InitializeComponent();
values = new Dictionary<string, string>();
}

private void button1_Click(object sender, EventArgs e)
{
SqlConnection connection =
new SqlConnection("[connectionString]");
connection.Open();
connection.InfoMessage += sc_InfoMessage;
SqlCommand comm =
new SqlCommand("pr_Test", connection);
comm.ExecuteNonQuery();
connection.Close();
string s = "";
foreach (KeyValuePair<string, string> pair in values)
{
s += string.Format("{0} : {1}\r\n",
pair.Key, pair.Value);
}
label1.Text = s;
}

private void sc_InfoMessage(object sender,
SqlInfoMessageEventArgs e)
{
string commandPrefix = "Eval: ";
foreach (SqlError err in e.Errors)
{
if ((err.Message ?? "").StartsWith(commandPrefix))
{
string command =
err.Message.Substring(commandPrefix.Length);
string[] cmd = command.Trim().Split('=');
string commandArgument = cmd[0];
string commandValue = cmd[1];
values[commandArgument] = commandValue;
}
}
}
}
}


In this scenario I have a simple form with a button and a label. I execute a pr_Test stored procedure and then I parse the messages it returns. If the messages are of the format
Eval: Name=Value
I store the keys and values in a Dictionary. Not the nicest code, but it's for demo purposes.

So, you want to know the count of whatever operation you executed? Add
PRINT 'Eval: RowCount='+cast(@@rowcount as varchar)
in your stored procedure. Pretty cool huh?

Unfortunately I haven't been able to send messages asynchronously, even if the connection was async and the running was async and the messages were generated with
RAISERROR('message',1,1) WITH NOWAIT
. BTW, who is the idiot that spelled RAISERROR with only one E? What's a Rror and why would I raise it?