This example can be done pretty simply using expressions for the Send Email task.
Instead of all this scripting, simply set the Subject expression to "Status for Order: " + @[User::str_OrderNum] and the Body to "The order number: " + @[User::str_OrderNum] + " placed on " + @[User::str_OrderDate] + " is ready for shipment. Please generate invoice for amount: " + @[User::str_AmountDue]. Now this approach might be more suited for some complex querying with loops, e.g., Multiple orders or order with line item detail, but even then I would use another approach. You should be using expressions for email tasks anyway, as I HIGHLY recommend using configurable package variables that become expressions for the To and CC line of ANY email function.
For very complex emails I would highly recommend creating a stored procedure that returned a nicely formatted HTML string to be the message body. Especially for internal corporate operations where evryone is viewing the email with the same tools. Two side benefits of this are you can modify either the content or presentation of the data without cracking open the SSIS package, and you can replicate the email for static data simply by calling the procedure, e.g., Payments made on a certain day or hours worked at a location by an employee.
If someone wants me to put together a demonstration of that I can. Additionally there may be a nice graceful solution using XML and XSLT, since XML is an output format for 2005 and beyond, however HTML must be hand crafted with embedded HTML formatting commands.
Honestly, I think script based email should be a VERY last resort. Expressions, albeit a bit awkward for lots of information, are a better approach to dynamic data. Not to mention having to store the binary code for any script in the dtsx package which is a hog (Use notepad to look at a script laden dtsx file sometime).
As for locking variables, I do prefer Manish's approach of using the ReadOnly and ReadWriteVariable declarations in the script window as opposed to locking functions in the script. It is more evident what variables the script is using, less things can go awry, and unless you have very long running scrips AND (not OR) concurrent process that use them, it isn't necessary so why assume that unnecessary burden. Sure they may be locked for 20ms more than necessary, but what other process is using them? They are scoped at the package instance level so the only contention is inside your own package instance.