« December 2003 | Main | February 2004 »
January 29, 2004
Forcing .ASPX Compilation
John Lam wrote an article about Forcing Compilation of ASPX Pages without executing them within the server context. Since ASPX pages are a necassary evil in our current software architecture, I would love to be able to precompile them before they are deployed. Apparently PageParser.GetCompiledPageInstance(), can help accomplish this. Also interesting is this article about Hosting ASP.NET Outside of IIS.
Posted by 0xFF3300 at 03:48 PM | Comments (2) | TrackBack
January 28, 2004
Core J2EE Patterns - Data Access Object
Core J2EE Patterns - Data Access Object
Access to data varies depending on the source of the data. Access to persistent storage, such as to a database, varies greatly depending on the type of storage (relational databases, object-oriented databases, flat files, and so forth) and the vendor implementation.
Posted by 0xFF3300 at 10:19 AM | Comments (0) | TrackBack
January 22, 2004
Mono 0.30 Preview Release Available
The first preview in a series for the Mono 0.30 release is available
here:
http://www.go-mono.com/preview/mono-0.30.tar.gz
http://www.go-mono.com/preview/mcs-0.30.tar.gz
We are just looking for obvious problems and mistakes that might be
in there. We are hoping to make a release early next week. Please
report any compilation problems in your platform.
Posted by 0xFF3300 at 01:27 PM | Comments (1) | TrackBack
January 21, 2004
FireDaemon
Here's a good replacement to SRVANY.EXE, if you don't have access to the Windows Resource Kit.
FireDaemon :: Install and run Win32 applications as Windows NT/2K/XP/2K3 services
Posted by 0xFF3300 at 11:54 AM | Comments (1) | TrackBack
January 19, 2004
Microsoft Offers Linux-Interoperability Software For Free
Microsoft has decided to drop the $99 licensing fee previously required for its Services For Unix software and plans to make a new version of the interoperability product available this week at no cost on its Web site.
Services For Unix is a subsystem of Unix APIs and development and administration tools intended to help businesses migrate Unix or Linux applications to Windows computers or create heterogeneous environments where the operating systems coexist. SFU version 3.5, to be available Thursday, will come with performance improvements and new features that make it better at both of those functions, yet Microsoft officials say the price change represents a strategy shift that's equally important.
"The big news on this release, we think, is that it's free," says Dennis Oldroyd, a director with Microsoft's Windows server group.
Microsoft had developed a reputation among some customers for not doing enough to help them deal with the growing number of mixed computing environments. In a survey last fall by InformationWeek Research, more than half of the 400 business-technology professionals who responded said Windows-Linux interoperability was a problem, and 87% were of the opinion that Microsoft was leaving the interoperability work to others.
"The real driver behind this [pricing] change is this interoperability issue," Oldroyd says. "We want Windows to be the best platform for interoperability."
The three main components of SFU--Unix's Network File System and Network Identity Service and Microsoft's Interix layer of Posix APIs--have all been tuned for better performance, with some commands running 50% faster, Oldroyd says. SFU 3.5 also features first-time support for P-Threads (for Posix-compliant multithreaded applications), a broader set of Posix APIs, and updated utilities and libraries.
Posted by 0xFF3300 at 03:58 PM | Comments (1) | TrackBack
January 17, 2004
mod_mono INSTALL
Daniel Lopez Ridruejo
http://www.apacheworld.org
The following are instructions for getting mod_mono working with Apache 2
and serving ASP.NET pages. This was developed in Red Hat 8.0,
using the Mono version from CVS, but it should work in any Unix platform
that Apache and Mono support. If you get to work in one of these platforms,
or Windows, please let me know, or even better send patches.
It has also been compiled and tested in Slackware 7.0 (thanks John Barbee)
The steps are as follow:
- Install mono
- Install Apache 2 with loadable module support
- Build mod_mono and ModMono.dll (or download the binaries)
- Configure Apache
- Install XSP from the Mono CVS repository
- Configure Apache
- Test the examples
There's also a section about using mod_mono with the Apache 2 that comes
with your Linux distribution. Finally, if you are using Red Hat 8.0
there's an appendix covering this platform.
mod_mono is still in its infancy and Mono is a moving target, there's still a lot to be done!
If you have suggestions, bugs or patches you can reach me at daniel @ rawbyte.com
It may take me a bit, but I try to reply to all mod_mono related email
INSTALLING FROM SOURCE
======================
1. Install Mono
For instructions, go to http://www.go-mono.com
2. Install Apache 2, with loadable module support
Go to http://www.apache.org and download Apache 2,
the filename will be something like httpd-2.0.43.tar.gz
Unpack it :
tar xvfz httpd-2.0.43.tar.gz
cd httpd-2.0.43
./configure --prefix=/home/username/apache2 --enable-so
make
make install
3. Building and installing mod_mono
Go to http://www.apacheworld.org/modmono/ and download mod_mono
(although if you are reading this you probably already did it)
tar xvfz mod_mono*.tgz
cd mod_mono*
./configure --with-apxs=/home/username/apache2/bin/apxs
make
make install
If everything goes well, you will have the following library:
/home/user/mono/mod_mono/src/.libs/libmod_mono.so
Mono needs to be correctly installed for building mod_mono, this means among other things
that pkgconfig is accessible and knows about mono (that is 'pkgconfig --cflags mono' returns
something meaningful)
NOTE:
If you installed Mono form CVS in a non standard location, you can use --with-crosspkgdir
For example: I use the following line to build:
PKG_CONFIG_PATH=/home/user/mono/install/lib/pkgconfig/ ./configure --with-apxs=/home/user/mono/install/apache2/bin/apxs --with-crosspkgdir=/home/user/mono/install/lib/pkgconfig
If it complains about config.h, copy the config.h in the mono/ directory to /home/user/mono/install/include
It will tell you about duplication, but it will compile. This should have been fixed as of Mono 0.18
4. Building ModMono.dll
The ModMono.cs file is located in the src/ directory
This is the command to build ModMono.dll:
make -f makedll.mak
INSTALLING BINARIES
========================
o Go to http://www.apacheworld.org/modmono and download the mod_mono binaries.
Currently the binary files are libmodmono.so (for Red Hat 8.0 on Intel) and ModMono.dll
USING THE APACHE 2 THAT COMES WITH YOUR DISTRIBUTION
====================================================
Newer versions of Linux distributions, such as Red Hat 8.0 come with Apache 2.
You can use this Apache: for that you need to install the apxs tool, which
is usually included in the Apache dev rpm. For example, in the case of Red Hat 8.0,
you need the following dev package installed: httpd-devel-2.0.40-8.i386.rpm
You can then build mod_mono as explained previously using
./configure --with-apxs=/usr/sbin/apxs
Red Hat 8.0 is so common that I have included a section at the end with step by
step instructions for this platform.
ASP.NET support
===============
You need the XSP package, currently available in the Mono CVs. GO to
http://www.go-mono.com for instructions on how to download and install
the package. The rest of this document assumes it is installed in
/home/user/mono/install/xsp/
cd /home/user/mono/install/xsp/
make
make install
Now in /home/user/mono/install/xsp/server/test you have a directory with ASP pages
CONFIGURING APACHE
==================
Copy the file /home/user/mono/mod_mono/src/.libs/libmod_mono.so to /home/user/mono/install/apache2/lib/
Copy ModMono.dll to a place where the Mono runtime will find it, usually this means /usr/lib/ or wherever the
rest of assemblies are located.
Edit /home/user/mono/install/apache2/conf/httpd.conf :
Listen 8080
LoadModule mono_module /home/user/mono/install/apache2/lib/libmod_mono.so
MonoApplication /mono /home/user/mono/install/xsp/server/test
The MonoApplication directive takes two arguments. The first one is the virtual path, which is part
of the URL used to access your application. The second one is the physical path, the directory
where the application resides. In this case is the directory containing the XSP test pages.
Only one MonoApplication directive is currently allowed.
NOTE: If a machine.config is not installed in your path, which normally occurs during Mono installation,
you may need to create a ModMono.exe.config. This file needs to be placed in the application base dir, in this case
/home/user/mono/install/xsp/server/test/
You can find an example for the contents of this file in the data/machine.config subdirectory of the Mono distribution.
You can now start Apache with
/home/user/mono/install/apache2/bin/apachectl start
TESTING THE EXAMPLES
====================
Point your web browser to
http://127.0.0.1:8080/mono/index.aspx
and you should get the example index.
If you get a Internal Server Error page instead, take a look at
/home/user/mono/install/apache2/logs/error_log
for indications of what may have gone wrong
APPENDIX: RED HAT 8.0
=====================
a) Install Mono
Install the Mono rpms from
http://www.go-mono.com/download.html
b) Install Apache
Make sure the followings rpms are installed
httpd-2.0.40-8.i386.rpm
httpd-devel-2.0.40-8.i386.rpm
You can find a copy of them at
http://www.rpmfind.net/linux/RPM/redhat/8.0/i386/httpd-2.0.40-8.i386.html
http://www.rpmfind.net//linux/RPM/redhat/8.0/i386/httpd-devel-2.0.40-8.i386.html
To install them:
rpm -i httpd-2.0.40-8.i386.rpm httpd-devel-2.0.40-8.i386.rpm
c) mod_mono
Follow the instructions at http://www.go-mono.com/anoncvs.html,
which is as follows:
export CVSROOT=:pserver:anonymous@anoncvs.go-mono.com:/mono
cvs login
cvs -z3 co mod_mono
Now cd into the mod_mono directory
./autogen.sh --with-apxs=/usr/sbin/apxs
make
make install
You need to become root (use the 'su' command) to do make install,
as it will try to copy mod_mono.so to the /usr/lib/httpd/modules/
directory
To build ModMono.dll, cd into mod_mono/src and type
make -f makedll.make
cp ModMono.dll /usr/lib/ModMono.dll
d) XSP server pages
Follow the general instructions explained earlier in the document
You need to make sure the directory where the aspx files are is writable by
the user Apache will be running as:
chown -R apache.apache /home/user/mono/install/xsp/server/test
e) Configure Apache
Edit the /etc/httpd/conf/httpd.conf file and add the following:
LoadModule mono_module mod_mono.so
MonoApplication /mono /home/user/mono/install/xsp/server/test
The following is a temporary hack, will not be necessary in the future:
mkdir /var/www/.wapi/
chown apache.apache /var/www/.wapi
chmod 700 /var/www/.wapi
f) Start apache
As root, type:
/etc/init.d/httpd start
g) Browse the examples
http://127.0.0.1/mono/index.aspx
If you find any problems, take a look at
/var/log/httpd/error_log and also read the
FAQ.txt document included with mod_mono
Posted by 0xFF3300 at 08:09 PM | Comments (0) | TrackBack
January 16, 2004
XSP Server Install Errors
When installing the mono XSP server I get the following error:
su-2.05b# make
Making all in doc
Making all in server
Unknown modifier ','
/usr/local/bin/mcs -debug+ -debug:full -nologo ) /out:xsp.exe
Syntax error: ")" unexpected
*** Error code 2
Stop in /root/mono-install/xsp-0.8/server.
*** Error code 1
Stop in /root/mono-install/xsp-0.8.
su-2.05b#
The fix is to use gmake instead of make. Yeah!
Posted by 0xFF3300 at 08:32 PM | Comments (3) | TrackBack
Integration of NAnt with NUnit Bug
I have placed the following lines in my build.xml.
<nunit2>
<test assemblyname="bin/debug/WebDAOI.dll" outfile="results.xml"/>
</nunit2>
When I run NAnt, it gives the following error:
The located assembly's manifest definition with name 'nunit.framework' does not match the assembly reference.
If I remove the <nunit2> line from the build.xml, NAnt is able to create the assembly perfectly, and I am able to test the same in NUnit from the GUI.
Moreover, while building the assembly using NAnt, I have included the reference for nunit.framework.dll. Seems like I am missing some other reference.
NAnt uses precompiled NUnit using some particular version of nunit.framework.dll. Most likely this version is not what you've compiled
your assembly against.
Try recompiling your dll, but instead of using nunit.framework.dll that comes with NUnit, use the one from NAnt.
Hope it helps,
Jarek
[0] [Nant-users] Integration of NAnt with NUnit
Posted by 0xFF3300 at 05:04 PM | Comments (1) | TrackBack
More Nant Complaints About
For God's sakes the Nant team considers the <record> task part of NAnt.Contrib.Tasks, why in the worlkd is it not a core task like Apache Ant!? It just makes it a pain to build. Can you ever think of time that you would not want the results logged in an AUTOMATED build environment?
<record>
A task that records the build's output to a file. Loosely based on Ant's Record task.
This task allows you to record the build's output, or parts of it to a file. You can start and stop recording at any place in the build process.
Posted by 0xFF3300 at 01:45 PM | Comments (0) | TrackBack
.NET Shared Source CLI Documentation
I have posted the .NET Shared Source CLI documentation here. Enjoy.
The Common Language Infrastructure (CLI) is the ECMA standard that describes the core of the .NET Framework world. The Shared Source CLI Beta Refresh is a compressed archive of the source code to a working implementation of the ECMA CLI and the ECMA C# language specification.
This implementation builds and runs on Windows XP and the FreeBSD operating system. It is released under a shared source initiative. Please see the accompanying license.
The Shared Source CLI Beta Refresh goes beyond the printed specification of the ECMA standards, providing a working implementation for CLI developers to explore and understand. It will be of interest to academics and researchers wishing to teach and explore modern programming language concepts, and to .NET developers interested in how the technology works.
Posted by 0xFF3300 at 10:21 AM | Comments (0) | TrackBack
Upgrading FreeBSD Ports with portupgrade
Most new and novice FreeBSD users do not yet take advantage of portupgrade. Here's 3 good articles to tell you how:
Got ports? Here is THE way to upgrade them!
portupgrade by Dru Lavigne -- One of FreeBSD's biggest benefits is its ports collection. Perhaps the most important ports utility is portupgrade. Dru Lavigne demonstrates how you can get the most out of your ports collection.
From the good 'ol manual Installing Applications: Packages and Ports
Posted by 0xFF3300 at 07:30 AM | Comments (1) | TrackBack
January 15, 2004
MONO_PATH Environment Variables
Chris says:
I'm trying to do an install of the new monodoc-0.9 and keep getting some sort of dependency error. I do the following:
1. ./configure
2. make -> and it blows up here.
I've tried to figure this out on my own for several hours now and to my
ability it looks like everything is in the right places.
Any help is appreciated.
The message become error message and spit out this:
error CS0006: Cannot find assembly `gtkhtml-sharp.dll'
Log:
error CS0006: Cannot find assembly `gtk-sharp.dll'
Log:
error CS0006: Cannot find assembly `glade-sharp.dll'
Log:
error CS0006: Cannot find assembly `glib-sharp.dll'
Log:
error CS0006: Cannot find assembly `pango-sharp.dll'
Log:
error CS0006: Cannot find assembly `gdk-sharp.dll'
Log:
error CS0006: Cannot find assembly `atk-sharp.dll'
Log:
Compilation failed: 7 error(s), 0 warnings
make[1]: *** [browser.exe] Error 1
make[1]: Leaving directory `/usr/src/monodoc-0.9/browser'
make: *** [all-recursive] Error 1
This should solve the problem:
export MONO_PATH=/usr/lib
and if that fails:
export MONO_PATH=/usr/lib:/usr/local/:lib
The key being you have to export environment variables. That's it.
Posted by 0xFF3300 at 05:22 PM | Comments (1) | TrackBack
Registry: Register .soap files as XML
Not too much to see here folks. All this registry change does, is register any .soap file on Windows as text/xml. When clicking on any .soap file, the it will cause the file to be opened in the Internet Explorer.
Download file, just click Open to install.
Posted by 0xFF3300 at 05:18 PM | Comments (2) | TrackBack
January 14, 2004
Parse Error, No Assembly Associated with Xml Key a1
When deserializing an oject from the FileSystem, I receive the following error:
An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in system.runtime.serialization.formatters.soap.dll: Parse Error, no assembly associated with Xml key a1.
The code basicallly looks like this:
string path = System.IO.Path.GetFullPath(testCasePath+"StatusTest-RV10.xml");
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
SoapFormatter formatter = new SoapFormatter();
ValueObject value = (ValueObject) formatter.Deserialize(fs);
The problem is I can deserialize a similar object without Exception. I have also tried using the full namespace of my ValueObject, but to no avail. The solution I finally ended up with was this:
Yes, actually I love it when I answer my own questions. If you look at the 'a1' value, it carries additional Assembly information; especially Version information. If the serialized file was created with a DIFFERENT Assembly version other than the one that is trying to read in right back in, the Soap Serializer will be unable to Deserialize. This is merely a safety measure to ensure that what you serialized out is what your are serializing back in.
<SOAP-ENV:Body>
<a1:ValueObject id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/N6k.Types/N6k.Types%2C%20Version%3D2.6.17.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6377e9412c0f826e">
</a1:ValueObject>
...
</SOAP-ENV:Body>
Posted by 0xFF3300 at 10:56 AM | Comments (3) | TrackBack
January 13, 2004
CMS Reviews
I think this is fairly good review of web-based Content-Management Systems. I gave Wordpess a shot, but for the small size of this site MovableType seems to work well. Chris writes "In the past two days I.ve installed over a dozen different .Content Management Systems. looking for my .ideal. CMS: it would need to be standards-complaint (preferably XHTML 1.0), it would need to include an easy-to-use template engine, it would need to have a news posting system (of course), it would need to have .static page. management (like through articles), it would need to use PHP/MySQL, it would need to have an active support community, and if it had a poll, a gallery, statistics, and a link directory available/integrated, that would be a plus. In short, I don.t need much in terms of user-end features, but quite a bit in terms of the core operation of the CMS."
Posted by 0xFF3300 at 09:06 AM | Comments (0) | TrackBack
January 12, 2004
How to make a quick links weblog in Movable Type
Thanks Mark, nice article.
How to make a quick links weblog in Movable Type: markpasc.org
Posted by 0xFF3300 at 04:34 PM | Comments (1) | TrackBack
Executing ASMX files without a Web Server
This console application from Jim Klopfenstein's Weblog, takes a SOAP message (on stdin) and an ASMX filename and a SOAPAction header (as command-line parameters) and returns the resulting SOAP message on stdout.
The ASMX file should be in the same directory as the executable; full paths are not supported.
Posted by 0xFF3300 at 04:06 PM | Comments (0) | TrackBack
SoapFormatter
Use of IFormatter is highly encouraged when Serializing/Deserializing objects to XML. There's a good reason for this, take a look at this example.
public class BankAccount
{
private System.Collections.ArrayList m_Mappings;
[XmlElement(typeof(AccountTypeMapping))]
public System.Collections.ArrayList Mappings
{
get{return m_Mappings;} set{m_Mappings = value;}
}
}
When the class is Serialized out, using just the XmlSerializer, it looks fine, but when Deserialized, the m_Mappings member is a zero-length array. But when it was Serialized it had 3 items inside of it. That's because the XmlSerializer does not Serialize private members, but won't it 'set' members loaded from XML that have public methods? No. So using the code below we get our desired result:
///
/// Simple Serialized
///
public static void toXML(object output)
{
FileStream fs =null;
try
{
string filename = output.GetType().FullName+".xml";
fs = new FileStream(filename, FileMode.Create);
SoapFormatter formatter = new SoapFormatter();
formatter.Serialize(fs, output);
fs.Close();
}
catch(Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
}
finally
{
fs.Close();
}
}
From the .NET Framework Documentation:
System.Runtime.Serialization.Formatters.Soap.SoapFormatter
The SoapFormatter and BinaryFormatter classes implement the IRemotingFormatter interface to support remote procedure calls (RPCs), and the IFormatter interface (inherited by the IRemotingFormatter) to support serialization of a graph of objects. The SoapFormatter class also supports RPCs with ISoapMessage objects, without using the IRemotingFormatter functionality.
During RPCs, the IRemotingFormatter interface allows the specification of two separate object graphs: the graph of objects to serialize, and an additional graph containing an array of header objects that convey information about the remote function call (for example, transaction ID or a method signature). For proper serialization, the root object of the first graph must be an object that implements either the IMethodCallMessage interface or the IMethodReturnMessage interface.
During deserialization of an RPC, a HeaderHandler delegate is specified to the Deserialize method of the formatter. The remoting infrastructure uses the HeaderHandler delegate to produce an object that supports the ISerializable interface. This object contains the information stored in the headers, and becomes the root of the graph returned by the deserializer.
The SoapFormatter can also handle RPCs that are produced with objects implementing the ISoapMessage interface. To create an RPC without using the IRemotingFormatter functionality, place an object that supports the ISoapMessage interface at the root of a graph being serialized. To deserialize an RPC created in this manner the TopObject property must be set to another object that supports the ISoapMessage interface, and contains the relevant remote call information.
Posted by 0xFF3300 at 10:38 AM | Comments (0) | TrackBack
NAnt Project Overrides
After reading message about project reference overriding: Re: [nant-dev] solution task addin and the documentation on SolutionTask, I am wondering if Nant Project Overrides were ever implemented, it's certainly a good idea. But upon reading the SolutionTask entry, there seems to be no such documentation. :(
"The SolutionTask allows you to build your projects in batches and use previously-built projects as part of your current build, using the reference configuration matching. As an example, we will examine a build file for a company that builds a set of core DLLs (projects-1.txt), followed by a set of other DLLs or applications (projects-2.txt). These files may be built in seperate NAnt build files, but for simplicity, we will place them in the same file."
Posted by 0xFF3300 at 08:17 AM | Comments (1) | TrackBack
January 11, 2004
Wiki Import Tools
Ever since I set up the new Wiki, I have been looking for an import tool. Basically I need to import existing HTML documentation. If something exists, drop me a line.
Posted by 0xFF3300 at 09:07 PM | Comments (0) | TrackBack
January 07, 2004
Cheap DVD Burner
I've been looking around for the cheapest DVD burner I could find and I came up with the Pioneer DVR-106 CD/DVD±R(W) for $119 at hypermicro. Thanks
Cheap Bastard!
Posted by 0xFF3300 at 09:43 PM | Comments (1) | TrackBack
Adding a Categories Section to MT
1.) Go to Weblog/Config/Preferences/Archives
2.) Check 'Archive Category Type'.
3.) In the Main Index, create a container where you want the categories to appear (for instance div="side")
4.) Enter this code. I've left off the brackets
MTCategories>
a href="$MTCategoryArchiveLink$>">$MTCategoryLabel$>/a>br>
MTEntries>
$MTEntryTitle$> br>
/MTEntries>
/MTCategories>
You don't need to use MTEntryTitle if you prefer not.
5.) If you want to set up categories before creating posts for those categories
add show_empty="1" after the first MTCategories tag.
Posted by 0xFF3300 at 03:40 PM | Comments (2) | TrackBack
Building a Challenge/Response Spam Blocking System
Interesting approach to Stopping Spam
Posted by 0xFF3300 at 03:13 PM | Comments (2) | TrackBack
January 06, 2004
SQL Server Locks - NOLOCK and ROWLOCK
I found a decent article that seems to explain proper use of NOLOCK and ROWLOCK. When working with large amounts of data, not using ROWLOCK can cause serious performance problems, for example incoming queries can basically be blocked by a SELECT statement to that table or even a JOIN on that same table. Note that SQL Server Optimizer hint NOLOCK is indentical to setting the transaction isolation level to READ UNCOMMITTED.
SQL Server Locks - NOLOCK and ROWLOCK
Posted by 0xFF3300 at 06:20 PM | Comments (0)
Why Lock(typeof(ClassName)) or SyncLock GetType(ClassName) Is Bad
Rico Mariani, performance architect for the Microsoft® .NET runtime and longtime Microsoft developer, mentioned to Dr. GUI in an e-mail conversation recently that a fairly common practice (and one that's, unfortunately, described in some of our documentation right now, although we'll be fixing that) is actually quite problematic. He asked if Dr. GUI could help get the word out that programmers shouldn't do this. The good doctor was delighted to oblige.
What is this fairly common practice? Well, it's getting a lock on a type object. In C#, it's lock(typeof(ClassName)) where ClassName is the name of some class; in Microsoft® Visual Basic® .NET, it's SyncLock GetType(ClassName).
A bit of background: The lock/SyncLock statement is used in multithreaded programming to create critical sections, or brief sections of your code where only one thread can execute at a time. (You might need this if you had to update more than one field in your object simultaneously—you'd want to make sure that another thread didn't try to update the object at the same time!) This statement locks the unique monitor object associated with the object you specify, waiting if another thread has the monitor already. Once it locks the monitor, no other thread can lock it until your thread releases the lock, which happens automatically at the end of enclosed block. A common usage is to lock the this/Me reference so that only your thread can modify the object you're using—or better yet, to lock the specific object you're about to modify. Locking the smallest possible object is good because it helps to avoid needless waiting.
So the type object is pretty handy. But some programmers have taken to using it as a "cheap" way of getting a proxy for a static/Shared object you can put a lock on. (And, unfortunately, we document this in both the C# and Visual Basic .NET documentation, implying that it's a recommended practice.) In this case, the docs are wrong (and we'll be correcting them). This practice is not acceptable, let alone recommended.
Here's why: Since there's one type object for all instances of a class, it would appear that locking it would provide a lock equivalent to locking a static object contained in your class. You would lock all instances of the class, wait until other threads were done accessing any part of any instance, then lock access so you could access static members safely and without another thread interfering.
And it does work, at least most of the time. But there are problems with it: First, getting the type object is actually a fairly slow process (although most programmers would guess that it's extremely fast); second, other threads in ANY CLASS and even different programs running in the same application domain have access to the type object, so it's possible that they'll lock the type object on you, blocking your execution entirely and causing you to hang.
The basic problem here is that you don't own the type object, and you don't know who else could access it. In general, it's a very bad idea to rely on locking an object you didn't create and don't know who else might be accessing. Doing so invites deadlock. The safest way is to only lock private objects.
But wait; it's even worse than all that. As it turns out, type objects are sometimes shared across application domains (but not across processes) in current versions of the .NET runtime. (This is generally okay since they're immutable.) That means that it's possible for ANOTHER APPLICATION running even in a different application domain (but in the same process) to deadlock your application by getting a lock on a type object you want to lock and never releasing it. And it would be easy to get access to that type object because the object has a name—the fully qualified name of the type! Remember that lock/SyncLock blocks (that's a polite word for hangs) until it can obtain a lock. It's obviously really quite bad to rely on a lock that another program or component can lock and cause you to deadlock.
Even if the type objects were unique to your application domain, this would still be a bad practice because any code could get access to the type object for a public type and cause a deadlock. This is especially a problem when you use components in your application that you didn't write. (Even lock(this)/SyncLock Me can have this problem, since someone else can lock you. Although if that happens, it's likely to be easier to find than the deadlock caused by locking a type object, since your object isn't globally available across application domains.)
So what should you do instead? Well, it's pretty easy: just declare and create an object to use as a lock, then use it, not the type object, to do your locking. Usually, to duplicate the intended semantics of the bad code, you'll want this object to be static/Shared—and it really, of course, should be private! In general, you could change the following bad code:
// C#
lock(typeof(Foo)) { // BAD CODE! NO! NO! NO!
// statements;
}
' VB .NET
SyncLock GetType(MyClass) ' BAD CODE! NO! NO! NO!
' statements
End SyncLock
…into the following good code:
// C#
lock(somePrivateStaticObject) { // Good code!
// statements;
}
' VB .NET
SyncLock GetType(somePrivateStaticObject) ' Good code!
' statements
End SyncLock
Of course, you'll have to either have a private static object to lock already (if you're using the lock to modify static objects, you may in fact already have one!) or you'll have to create one. (Make it private to keep other classes from locking your object.) Do NOT attempt to lock a field that's not a reference (object) type, such as int/Integer. You'll get a compiler error. If you don't have a private static object to lock, you may need to create a dummy object:
// C#
Class MyClass {
private static Object somePrivateStaticObject = new Object();
// methods of class go here--can lock somePrivateStaticObject
}
' VB .NET
Class MyClass
Private Shared somePrivateStaticObject As New Object
' methods of class go here--can lock somePrivateStaticObject
End Class
You'll want to analyze each case separately to make sure you've got it right, but in general, the above technique should work.
Note a couple of things: First, no code outside of your class can lock MyClass.somePrivateStaticObject, so you've eliminated many opportunities for deadlock. And deadlocks are among the nastiest bugs to find, so eliminating opportunities for them is a very good thing.
Second, you know that there's exactly one copy of MyClass.somePrivateStaticObject for your application and exactly one for each other application on the system that is running, so there's no interplay across applications in the same application domain. Dr. GUI hopes you can see why this code is much more reliable and robust than the bad code.
To summarize, don't lock type objects. You don't know where they've been. Doing so is slow and can expose you to possible deadlock situations. It's a bad programming practice. Instead, lock a static object in your object.
This article came from Dr. GUI and was reprinted on serial.n6k.com.
Posted by 0xFF3300 at 10:45 AM | Comments (0)
January 05, 2004
Mono 0.29, MonoDoc 0.8, XSP 0.8 and mod_mono 0.6 Released
I think I'm about a week behind here, but Miguel and the folks Ximian have released Mono 0.29. I have just successfully installed the latest FreeBSD port without a hitch. Yes there were major problems with the previous port versions, but they're all better now. Life is better with a good port maintainer. Thanks gnome_at_FreeBSD.org!
There is big breaking news: Mono JIT on PowerPC runs Hello World, ASP.NET is feature complete, AppDomain unloading is supported and 64-bit ports of HPPA and SPARCv9 are available now. A new group of developers from Mainsoft has been contributing extensively to ADO.NET and ASP.NET.
This release includes four components at once: the Runtime and Software Development Kit as well as the Documentation browser, our XSP web host for ASP.NET and the Mono/Apache module have been released. Packages for various distributions are also available from our download page.
A big push in this release has been to get closer to completion on the .NET 1.0 and .NET 1.1 APIs and completing pieces that we need for the Mono 1.0 release. But at the same time work continues within the safety of #ifdefs on Mono 1.1 features (integrating .NET 1.2 components).
Posted by 0xFF3300 at 07:46 PM | Comments (0)
January 04, 2004
Attractive Things Work Better
I came across Don Norman's site; he's the writer of Emotional Design. I wonder if the 'Attractive Things Work Better' can be applied to core software design and architecture. I'm not referring to GUI design, but more underlying architecture. From a coding perspective, good-looking code is always better for readability, maintenance and a hundred other reasons. For software architecure, what would be considered 'attractive'? Well certainly the target audience would most likely not be end-users, but other software architects and/or developers. It's possible we could define this as 'Attractive Architectures'.
From Emotional Design:
"Noam Tractinsky, an Israeli scientist, was puzzled. Attractive things certainly should be preferred over ugly ones, but why would they work better? Yet two Japanese researchers, Masaaki Kurosu and Kaori Kashimura1, claimed just that. They developed two forms of automated teller machines, the ATM machines that allow us to get money and do simple banking tasks any time of the day or night. Both forms were identical in function, the number of buttons, and how they worked, but one had the buttons and screens arranged attractively, the other unattractively. Surprise! The Japanese found that the attractive ones were easier to use."
[0] Don Norman's jnd.org / books
Posted by 0xFF3300 at 09:52 PM | Comments (0)
January 02, 2004
Exception accessing custom section in Web.config
When attempting to access the custom section of a .NET Web.config file I received the following exception.
Parser Error Message: Could not load type System.Configuration.SingleTagSectionHandler from assembly System.Web, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a.
This is due to the fact that System.Web cannot access the System namespace. The full information about the Assembly System.Web is trying to load, including the PublicKeyToken, must be provided. Since I recently has this problem, I will share the solution I found. It works, but it clearly something that Microsoft should work on there Security model.
You need to add the assembly details to the type. When trying to load the
type, because the assembly name is not in there, the framework is looking
in the System.Web namespace. So, you need to modify it to the following:
<configSections>
<section name="sampleSection"
type="System.Configuration.SingleTagSectionHandler,System,
Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections>
<sampleSection setting1="Value1" setting2="value two" setting3="third
value" />
I tried this and this works. Please be sure that you have used the correct lower/upper case for the assembly names. I had this problem initially.
Posted by 0xFF3300 at 12:53 PM | Comments (1)
Compiling Mono 0.29
To get a functional Mono, the only piece you need to compile is `mono-0.29.tar.gz', the setup is very simple:
wget http://www.go-mono.com/archive/mono-0.29.tar.gz
tar xzvf mono-0.29.tar.gz
cd mono-0.29
./configure
make
make install
That is all you have to do.
Windows.Forms in Mono 0.29 is sadly broken (it is described on the
release notes for version 0.29). It is getting fixed, but it is not
yet ready, you will have to wait for that to actually work.
Posted by 0xFF3300 at 09:27 AM | Comments (0)
January 01, 2004
.Net Support For Apache
In July of 2003 Microsoft announced .Net support for Apache. Covalent had developed an Apache plugin-in to allow .NET support in Apache, but I haven't heard to much about it since then. I imagine it works similar to the mod_jk module.
"In a move designed to expand choices for Web developers, Covalent Technologies announced Wednesday that Apache 2.0, as available in Covalent's Enterprise Ready Server, is now compatible with Microsoft's ASP.NET."
References:
http://www.newsfactor.com/story.xhtml?story_id=18740
http://www.covalent.com/
Posted by 0xFF3300 at 07:53 PM | Comments (0)
Weblogs over XML-RPC
I wrote a little blurb a couple of weeks ago about publishing weblogs over XML-RPC, and lo and behold I stumbled across XML-RPC.NET which has a very nice .NET framework that can do such a thing. I also found this article which is basically a demo of how to implement the library.
Posted by 0xFF3300 at 07:36 PM | Comments (0) | TrackBack