Archive for October, 2006
Windows Workflow Foundation DTC Configuration Troubleshooting
Having spent some time working with WF ’s SqlTrackingService and SqlWorkflowPersistenceService to work with Sql Server 2005 on a seperate machine, I’ve put together a few links to help others.
NOTE: Certain transactions in Windows Workflow Foundation are promoted to DTC transaction when the stores are located on different machines.
- I found that the most helpful tool was DTCPing.
- A very easy program that can be used to test firewall issues and the simple connection between 2 computers over DTC.
- The second and more comprehensive was DTCTester.
- This will simulate a full sql transaction between computers.
CSharp IExtenderProvider with ExpandableObjectEditor for ValueLists
I’ve recently found a solution to a common problem of form development. Value lists or “CodeSets” for controls on user forms. Most of the time a programmer will write a stored procedure or statement to return some dataset and bind the results to a combo box, listview or similar control. I have several problems with this pattern.
- Can cause multiple queries to the database for a single form to load.
- Requires the programmer to write code for every control with an associated lookup table or value list.
- Could be implemented inconsistently.
What are our goals?
- Should require no code on the part of the programmer.
- Should cache the values of the codesets at runtime to avoid multiple database queries.
- Should be expandable to show both the name and id of the codeset.
So let’s solve this problem. I’m using Enterprise Library’s cache manager for caching and also EntLib’s data libraries for data access.
You’ll need 2 tables in the database:
- Codesets: The list of codeset identifiers and their descriptions.
- Codeset_Details: The list of values, it’s display value and the codeset identifier.
We create a custom component that implements IExtenderProvider that exposes a property called Codeset of type CodesetProperty.
The CodesetProperty class has a int and string member to store the id and name of the codeset to load into the control.
We need a custom typeeditor to show the available codeset values. NOTE: You will need to ensure you have access to the connection string for the current database. I do this through a registry setting pointing to our standard development directory which contains our app.config.
The last part is a custom typeeditor to return an InstanceDescriptor which the CodedDomSerializer will use to generate the Intialization code.
We then add a CodesetProvider to a form. In my case any combobox, listbox, dropdown and comboeditor will show a property “Codeset on codesetProvider1″. This is an expandable property so you’ll see the values listed but by dropping down the list on the property you will get a list of the available codesets and then at runtime this property will be used to load the combo box with the values.
No commentsService Broker An easier way: Service Listing Manager
I just found this great thread:
An easier way: Service Listing Manager
Setting up Service Broker routes, endpoints and security is just too hard. One has to run pages and pages of Transact-SQL code just to get the ‘Hello, world’ example work between two separate SQL Instances and the chances of making a mistake are overwhelming.
Well, not anymore! I’ve just uploaded into the Service Broker team code gallery a new GUI tool for doing just that: easily configure two services to be able to have conversations. The tool uses the ‘Service Listing’ concept. A Service Listing is like an identity card for a service. It is an XML document that contains all the necessary information needed to establish a conversation with that service. When two parties need to establish a conversation, they can exchange the Service Listings of the two services and the tool will create the entire infrastructure needed to establish the conversation. Optionally it can also create the message types and contracts supported by a target service in the initiator service database….
Here is a link to it:
Service Listing Manager
Notification Services Conversation Cleanup
While testing a Notification Services install I found I had alot of dead conversations left in my SYS.CONVERSATION_ENDPOINTS
DECLARE @HANDLE UNIQUEIDENTIFIER
DECLARE C CURSOR FAST_FORWARD FOR SELECT CONVERSATION_HANDLE FROM SYS.CONVERSATION_ENDPOINTS
OPEN C;
FETCH NEXT FROM C INTO @HANDLE;
WHILE @@fetch_status = 0
BEGIN
END CONVERSATION @HANDLE WITH CLEANUP
FETCH NEXT FROM C INTO @HANDLE;
END
CLOSE C;
DEALLOCATE C;
GO
You would need to add a check to make sure the timeout period has expired but this works nicely to cleanup any outstanding conversations.
For more info: Microsoft Blog Post
No commentsService Broker Fire and Forget Messages
I ran into the problem where I would send messages to the a remote service and the xml validation would fail. After checking the intiator side I couldn’t find an error message being returned from the receiving end. No event logs, nothing inserted into my error table… nothing. This got me digging around and I found a serious bug in my code.
I had purchased the Rational Guide to Service Broker 2005 by Roger Wolter and his pattern details the following:
DECLARE @conversationHandle uniqueidentifier
Begin Transaction
– Begin a dialog to the Order Service
BEGIN TRY
BEGIN DIALOG @conversationHandle
FROM SERVICE [TestCarolina_Message_Service]
TO SERVICE ‘Carolina_Message_Service’
ON CONTRACT [CarolinaOnly_Contract]
WITH ENCRYPTION = OFF, LIFETIME = 600;– Send a message on the dialog
SEND ON CONVERSATION @conversationHandle
MESSAGE TYPE [msg_to_carolina]
(@Message)END CONVERSATION @conversationHandle
END TRY
BEGIN CATCH
ROLLBACK
INSERT GENERAL.ERRORS (ERROR)
VALUES( ERROR_MESSAGE())
– Reenable queue
ALTER QUEUE TestCarolina_Message_Queue WITH STATUS = ON
END CATCHcommit
There is one glaring problem with this pattern. If an error happens on the receiving side, the conversation has already been ended on the sender’s side. When the Error is sent from the receiver, the message gets dropped, No EventLog, nothing. The conversation that the receiver is sending on does not exist on the sender anymore.
This leaves the question, how do we cleanup the conversation? Allow the receiver to end the conversation rather than explicitly end in on the sender. This requires the addition of an activated procedure on the sender’s queue that will handle the end conversations, but it adds the ability to handle error messages also. The following in pattern would be the correct way:
CREATE PROCEDURE usp_Message_Queue_Activation
AS
DECLARE @dh UNIQUEIDENTIFIER;
DECLARE @message_type SYSNAME;
DECLARE @message_body NVARCHAR(4000);
BEGIN TRANSACTION;
WAITFOR (
RECEIVE @dh = [conversation_handle],
@message_type = [message_type_name],
@message_body = CAST([message_body] AS NVARCHAR(4000))
FROM [InitiatorQueue]), TIMEOUT 1000;
WHILE @dh IS NOT NULL
BEGIN
IF @message_type = N’http://schemas.microsoft.com/SQL/ServiceBroker/Error’
BEGIN
INSERT Service_Broker_Errors
(error, [message]) values(N’Received error %s from service [Target]‘, @message_body);
END
END CONVERSATION @dh;
COMMIT;
SELECT @dh = NULL;
BEGIN TRANSACTION;
WAITFOR (
RECEIVE @dh = [conversation_handle],
@message_type = [message_type_name],
@message_body = CAST([message_body] AS NVARCHAR(4000))
FROM [InitiatorQueue]
), TIMEOUT 1000;
END
COMMIT;
GO– Create queue for messages to go to
CREATE QUEUE Test_Message_Queue
WITH ACTIVATION (
STATUS = ON,
MAX_QUEUE_READERS = 1,
PROCEDURE_NAME = [usp_Message_Queue_Activation],
EXECUTE AS OWNER);
GO
This would allow errors that occur during transmission to be handled gracefully.
No commentsColors in .Net
I found a nice page for finding the hex code of a particular color.
Another nice option is the FireFox’s extension Colorzilla.
This provides a mouse pointer RGB representation of the color under the pointer.
No commentsVisual Studio Code Snippets Editor
Snippy
I recently stumbled across this little program for managing your code snippets in Visual Studio.
The program is called Snippy the Visual Studio Code Snippet Editor. It made creating common code snippets for my company a breeze. Check it out at Snippy.
No commentsSql Server 2005 Notification Services and Remoted Services calls
I’ve recently have been working on a custom delivery protocol for notification services. I needed a way for sql server 2005 to call a remoted service when a trigger fired, to try and avoid polling the database for changes or using a SQLDependency that would need to be wired back up after each firing.
The delivery protocol takes 2 parameters from the instance config file: Service Contract Type (IServiceContract) and MethodName (The method to call).
On intialization I load the contract assembly in and reflect on the type to get the MethodInfo for later usage. It currently does not support overloaded methods and will only grab the first method match.
if (channelArgs.Count == 2)
{
string service = channelArgs["ServiceType"];
methodName = channelArgs["MethodName"];
Type t = TypeLoader.LoadType(service);
//I’m using windows security on my remoted object hosted in IIS, so setting the current principal is necessary.
Thread.CurrentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
MethodInfo[] myMethodInfos = t.GetMethods();
foreach (MethodInfo Mi in myMethodInfos)
{
if (Mi.Name == methodName)
{
myMethodInfo = Mi;
//Store the parameters for later usage.
info = myMethodInfo.GetParameters();
break;
}
}
}
else
{
throw new ArgumentException(
“Inadequate number of arguments supplied.”);
}
When a delivery notification comes in, I take the list of ProtocolFields and match them to the method parameters and invoke the method.
bool successfulDelivery = false;
Exception failureException = null;
try
{
foreach (NotificationHeaders header in headersList)
{
object[] param = null;
// Set the method parameters.
if (null != header.ProtocolFields)
{
param = new object[header.ProtocolFields.Count];
int idx = 0;
foreach (string protocolField in header.ProtocolFields.Values)
{
Type tp = info[idx].ParameterType;
object o = Convert.ChangeType(protocolField, tp);
param[idx] = o;
idx++;
}
}
object obj = ServiceFactory.CreateInstance(t, service);
myMethodInfo.Invoke(obj, param);
}
}
catch (Exception ex)
{
failureException = ex;
// Handle any exceptions here; for instance,
// write exception information to the event log.
}
finally
{
SendStatus(headersList, successfulDelivery,
body, failureException);
}
You will need to make sure RemotingServices.Configure has been called before the method is invoked. Also the ServiceFactory is a helper to extract the particulars of creating the object away from any client code to allow for future support of Windows Communication Foundation (WCF) or any other communication protocol. SendStatus returns the message status to Notification Services.
There is certainly some cleanup that needs to occur but the jist is there. This allows Sql Server 2005 to call back to any service when an event occurs in the database. Next I’ll post the application config files to setup the service.
1 commentDesignMode and Checking Design Mode on a WinForm
DesignMode checking can be troublesome with form inheritance. An example would be a base form has an OnLoad that does something
private void OnLoad(object sender, EventArgs e)
{
if (!DesignMode)
{
//Do something here.
}
}
Where the trouble starts is when the derived form is loaded in the visual studio designer. DesignMode solving to true in the base form is not always guaranteed, therefore an acceptable solution would be the following:
///
/// Indicates if the current view is being utilized in the VS.NET IDE or not.
///
public new bool DesignMode
{
get
{
return (System.Diagnostics.Process.GetCurrentProcess().ProcessName == “devenv”);
}
}
Framework Design Guidelines
First things first, I’m a strong advocate that every .Net developer should read the book Framework Design Guidelines by Krzysztof Cwalina and Brad Abrams. (ISBN: 0321246756) I’ve read it 3 times from front to back and refer to it on almost a daily basis. As this reviewer puts it, “Nothing less than wisdom distilled”.
Nothing less than wisdom distilled, November 7, 2005
Reviewer: John Gossman (Seattle, wa USA) - See all my reviews
At Microsoft I work on a development team that has been using the guidelines from this book for nearly 4 years. I am not always a fan of coding standards, thinking they are a necessary evil, often simply arbitrary choices made for consistency.
The Framework Design Guidelines are different. These ensure deep consistency across not just source code, but more importantly the public classes themselves. They include critical, not to be ignored rules on security, cross-language access and localization, as well as the usual good practice type guidelines. But even these “good” practices are always backed with well reasoned argument and examples. As an added bonus FxCop provides a static analysis tool that enforces the guidelines.
Finally, the Framework Design Guidelines provide deep insight into how the .NET Frameworks are designed and used. With the guidelines in mind it is far easier to remember or even guess what classes are provided and how they should be used. This just makes the libraries that much more productive.
The insights enclosed show the trials and tribulations Microsoft had developing the .NET Framework and will surely help you prevent the same problems in your software designs.
No comments