Archive for May, 2005

OpenDoubleListBox, I knew I was forgetting something

Posted in Programming, .NET, Software, ASP.NET, Open Source on May 31st, 2005

I apologize, I setup a new site and didn’t move over the OpenDoubleListBox files. I didn’t even realize it until I received an email today. Thanks for the reminder Noah.

Current files for the OpenDoubleListBox:
DoubleListBox Example Project
OpenDoubleListBox binary
OpenDoubleListBox Source Code

If you don’t know, the OpenDoubleListBox is a open source implementation of a .NET server control for a double list box . Written in C#. See an image here.

I have also received several requests for additional functionality. I hope to be releasing a new version when I get the time. You can read more about the control at ASP.NET.

Trackback Test

Posted in Technology Trends, Blogging on May 29th, 2005

While wondering if trackbacks were indeed working, and trying to figure out what exactly a trackback is, I came across someone in the same situation. So I decided to take the time to trackback this to his post to test Trackbacks.

In theory this message should appear as a comment in his blog. Which he first has to approve.

Now I wonder what would happen if someone trackbacks a trackback?

Linksys Wireless-G Broadband Router (WRT54G) for 42.99 AR

Posted in Deals, Hardware, Wireless on May 28th, 2005

The Linksys Wireless-G Broadband router is probably the most ubiquitous router for home users. And for good reason! There are numerous firmwares to hack this device to fit your needs. And even without the rebate is this a good deal. The list of availble firmwares is always growing, from Earthlink’s IPv6 hack to Sveasoft, which adds dozens of features. Read more about the WRT54G at Wikipedia or visit the Linksys Info Forum.

New website makes finding cheap gas easier

Posted in Technology Trends, Deals on May 27th, 2005

Just in time for Memorial day, AAA has debuted a new fuel price finder. You may already use the Gas Buddy or the new Gas Buddy powered by Google maps. Which uses the Google Maps API. But whereas Gas Buddy relies on volunteer sponsers, AAA gets it’s data from credit card transactions. Now I will admit I am a touch worried about what form they actually get this data. But there is also a delay to get the data, it appears some of the prices are anywhere from 0 to 7 days old.

The service works by the user selecting a city and state or entering a zip code. And selecting a 3, 5 or 10 mile radius. It then displays a map and a list of service stations with the prices for regular, mid, premium, and sometimes diesel. Click on a service station and the finder will center the station on the map.

Enjoy.

Tag your way out of digital clutter

Posted in Technology Trends, Tagging on May 27th, 2005

For anyone who has ever seen the 1966 Batman movie and laughed over the ridiculous signs hanging around the Batcave this one’s for you. It appears “tagging” is now all the rage and promises to liberate us from having to sort through too much data. Most tagging involve social networks, such as del.icio.us, 43 Things, Flickr, and Technorati.

Some offline applications have also introduced tagging, namely the Adobe Photo Album. Hopefully one day more tagging applications will be available to tag everything on our PC, from email to Word documents. In the meantime I will be going around the office affixing signs to everything, “Bat-Watercooler”, “Bat-Printer”, “Bat-Web Server” ….

Mainstream Podcasts

Posted in Podcasting, Technology Trends on May 27th, 2005

Our local channel 9, WCPO in Cincinnati, has made available their afternoon newscast available as a podcast. This is obviously intended as a test of the technology and hopefully more will follow. I have only one request, make the URI for the feed bigger. I scanned the page several times for the podcast feed only to find it’s hidden in 6 pt font.

E.W. Scripps, the owner of WCPO, has recently made a move to distribute content via the web. It’s new Living.com is a new all-video Web site that will use programming from its Food Network, Fine Living, HGTV and DIY Network brands, as well as new clips.

Getting started with your WebRamp 700s

Posted in Networking, Security, Hardware on May 26th, 2005
How to connect a Webramp 700s to DSL/Cable Modem

Getting started with your WebRamp 700s

So you bought you a WebRamp 700s? A good choice at less than 30 dollars. It’s value far greater than that, I can assure you. I made a list of steps to follow if you are connecting the WebRamp 700s directly to your Cable or DSL modem.
Note: This assumes you already know how to get to the admin console for your WebRamp 700s. The defaults to which are IP address: 192.168.1.251, login with username ‘admin’ and password ‘password’. You must have a java enabled browser.

1. Choose Advanced from menu bar, Intranet Tab
2. Select Webramp 700s WAN link is connected directly to the Internet router
3. Press Update
4. Select General from menu bar, Network Tab
5. Change Network Addressing Mode to NAT with DHCP
6. Press Update
7. Select DHCP from menu bar, Setup Tab
8. Enable DHCP Server
9. Set Client Default Gateway to 192.168.1.251 (the IP address of the webramp)
10. Press Update
11. Restart router Tools menu - Restart tab - Restart WebRamp 700s button
12. This takes about a minute, when restart is complete - goto DHCP menu - Setup tab and verify DNS is set to “Set DNS servers using Webramp 700s Network settings”
13. Press Update if necessary

Note: Obviously the DSL/Cable modem should connect directly to the WAN port on the back of the WebRamp 700s and the PCs (or hub) connect to the ‘TO COMPUTER’ ports.

This was my initial test of the WebRamp 700s. I have since setup my WebRamp to work with my Linksys WRT54G Wireless Router. The instructions for which are slightly varied, yet no more difficult, and I will post that soon.

Multi-threaded Applications: Making Asynchronous calls to a .NET web service

Posted in Programming, .NET, Web Service on May 26th, 2005

The Business Case
I am currently designing a Customer Inquiry screen for our customer support personnel. I built a Windows application in VB.NET to retrieve and view large amounts customer data from different areas of the enterprise. Business requirements stated to return customer information, such as address and tax information, purchase history, and open orders.

I decided to create a Web Service to handle the functionality of retrieving customer details from the SQL Server. This way I could create a Windows application or a web application and use the same components. Even if a remote user wants to use a Windows application, the web service can retrieve customer data from the home office.

I will assume you are already familiar with the creation of a web service, if not this article maybe difficult to understand. I completed the functionality of my web service, what I call SEER services. The SEER services will forever be my one stop shop for customer information. Currently it performs five functions, including, searching by customer name or number, retrieve past invoice history, calculate customer spending by fiscal year, and retrieving open orders.

Creating and Calling a Multi-threaded Web Service
You don’t have to do anything special to create a multi-threaded web service. The .NET framework already handles this. For each of your WebMethods, .NET creates several more methods; giving your web service that asynchronous touch. Ok, let’s say I have a function called getInvoiceHistory, .NET has also created a method called BegingetInvoiceHistory and EndgetInvoiceHistory. Only calling this method is slightly different from calling the method normally. Let’s look at the differences.

I have previously declared a Dataset as dstDataSet, my web service as seerservices, and selectedCustomer is a string containing the customer ID who I am retrieving the data for. In my single threaded days, I would have simply retrieved customer data in this fashion.

dstDataSet = seerservices.getInvoiceHistory(selectedCustomer)

But in the asynchronous world that same method call would look something like this.

seerservices.BegingetInvoiceHistory(selectedCustomer, acCustomerRecords1, 0)

As you can see more parameters needs to be passed to our asynchronous method than the synchronous method. The first value is a string with the customer ID, same as before. But the next value is another object called AsyncCallback. I used the following declaration to create that object.

Private acCustomerRecords1 As AsyncCallback

        acCustomerRecords1 = New AsyncCallback(AddressOf Me.onCompletedCustomerRecords1)

This will allow a local function onCompletedCustomerRecords1 to handle the returning data. In order to complete the threaded call you will need to call EndgetInvoiceHistory, or Endxxxxxx where xxxxxx is your function name.

Private Sub onCompletedCustomerRecords1(ByVal asyncResult As IAsyncResult)
             'Declare the web service
            Dim seerservices As New SeerServices.seer
            Try
                'Returns the dataset to a class variable (why is explained later)
                _dstDataSet1 = seerservices.EndgetInvoiceHistory(asyncResult)
                'Bind the dataset to my datagrid
                Me.BeginInvoke(CallDataBindToDataGrid)
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical, "Error!")
            End Try
        End Sub

Notice the function declares the web service and then calls the EndgetInvoiceHistory function. This will retrieve the return value from the function.

Summary
That’s it; to call an asynchronous web service you just follow a few steps. And before I tie up some loose ends, let’s go through these steps again.

1. Declare a AsyncCallback object

Private acCustomerRecords1 As AsyncCallback
acCustomerRecords1 = New AsyncCallback(AddressOf Me.onCompletedCustomerRecords1)

2. Call the thread friendly version of your web service function. Again you don’t have to do anything to your web service. This function is created automatically by .NET.

seerservices.BegingetInvoiceHistory(selectedCustomer, acCustomerRecords1, 0)

3. Create a function to handle the thread after completion.

Private Sub onCompletedCustomerRecords1(ByVal asyncResult As IAsyncResult)
        Dim seerservices As New SeerServices.seer
            Try
                _dstDataSet1 = seerservices.EndgetInvoiceHistory(asyncResult)
                Me.BeginInvoke(CallDataBindToDataGrid)
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical, "Error!")
            End Try
      End Sub

Calling out of thread objects
Ok, now your probably wondering what Me.BeginInvoke means. This is a little off topic but I will through it briefly. DataBindToDataGrid is a method that will bind the class property _dstDataSet1 to a datagrid on my form. Now CallDataBindToDataGrid is a previously declared MethodInvoker object that will call the aforementioned function.

Dim CallDataBindToDataGrid As New MethodInvoker(AddressOf Me.DataBindToDataGrid)

The reason for this is, a datagrid is a single instance object and it’s methods cannot be accesses while in a thread. The BeginInvoke method will call the datagrid databinding properties and assign _dstDataSet1 as its data source. Try binding the dataset directly to the datagrid in this function, or even calling DataBindToDataGrid function directly and an exception will be thrown. The gist of the error is, “Controls created on one thread cannot be parented to controls created on another thread” or you can’t call methods of a single-threaded object outside your thread.

Public Sub DataBindToDataGrid()
        dgHistoryDetail.DataSource = _dstDataSet1
        dgHistoryDetail.DataMember = "invoiceheaders"
        _dstDataSet1 = Nothing
    End Sub

Conclusion
The main reason I chose this approach to data retrieval is it speeds up database access. Instead of each function retrieving and binding the data in order, each function is done simultaneously. And the fact that the UI is still responsive while the data is loading will make it easier on the user. You will be amazed by the fact you can still manuever around the user interface while your application is working in the background.

References
Griffiths, Ian. Give Your .NET-based Application a Fast and Responsive UI with Multiple Threads. MSDN. Feb 2003. Aug 9, 2004. http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/

Meier, J.D., Srinath Vasireddy, Ashish Babbar, Alex Mackman. Improving Web Services Performance. Improving .NET Application Performance and Scalability. May 2004. Aug 9, 2004. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt10.asp