Golden Rule of Winform Databinding

Rocky Lhotka had this over on his site:

The Golden Rule of Windows Forms data binding

Never directly interact with a business object while it is data bound – only interact with the bindingsource

http://forums.lhotka.net/forums/thread/22990.aspx

I have to say, I am guilty of doing this, and I didn’t even know it was considered a bad practice, but I do recall running into problems with the behavior in getting the UI to refresh as I would want it to.

I also found a nice article talking about how to speed up binding to the datagrid:
 

Why should you not use floats for actual decimal numbers?

I don’t think etrade has learned the lessons in my posts on floating point numbers/variables.

SQL Server Decimal/Money/Float datatypes

Javascript (and apparently other programming languages) can’t do math

Click here for a screen shot of the full page.

Here is a link to the page where I found it. I hope they fix it soon. It’s pretty sad.

But, on the other hand, I wonder what I will do with that extra .00000000000005 dollars?

Trying to find the WIFI Switch on the HP Elitebook 8730w?

It took me a while to figure out that I didn’t have a driver problem.

I was looking everywhere to find the switch for the wifi on this HP Elitebook 8730w, but it turns out the LED icon in the upper left that shows the WIFI status IS the button, but clicking it does nothing.. why?

Well, b/c HP is using “LAN/WLAN switching” which means that it automatically turns off the wifi connection if you are plugged in.

Just unplug your network cable and your wifi card will enable! 

 

SQL Reports RDLC Errors

Ever get this error?

More than one data set, data region, or grouping in the report has 
the name 'SOMENAME'.  Data set, data region, and grouping names
must be unique within a report. 

Basically what happened was, somehow VS lost track of an existing datasource you were using, why I don’t know. When you went to add a new field or change something it added a 2nd copy of the same datasource, and now you have 2 datasources with same name. You can’t do that. To fix this, when you are editing the report, choose Report –> Data Sources from the menu and remove one of the duplicate datasource names.

In a related error, you may notice that you can’t use some fields that are part of your dataset.  For example, in my app, I had a field called “CreatedDate”.  This was a public property of my object, and it showed up in my data source that I was using to bind to the report, but the report refused to acknowledge it.

So in this case you need to delete the original datasource using the same steps as above, and do something to cause it to add a new copy of the correct datasource (like drag a field onto the report).

Problems Upgrading VS Solutions to 2008 With CruiseControl.Net

Problem:

We have a server that gets all files from TFS and uses Nant w/ Visual studio to compile our projects.  Basically nant issues a command line statement to get VS to build a given solution.

Everything was working great, until I upgraded our clients to 2008.

I went through and upgraded all our solutions.

I installed vs 2008 on the server.  But when I try to build from the command line, it tells me that the solution file “is from a previous version of this application and must be converted in order to build in this version of the application.”

I tried directly copying my solution file (skipping the source control step) directly to the server but I get the same message.

If I try to build it from the command line with VS 2005 it tells me that the solution is too new!! 

So 2005 says the solution is too new, 2008 says it is too old!

The solution on the server has the “version 9” icon, just like on my laptop.

The solution file starts with:
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008

Resolution:

Even thought I compared the solution files and found them to be exactly the same using a diff compare tool, I allowed the server to run the “upgrade” process on the solutions.  I didn’t save any of the changes it made, but from then on it recognized those files as having been already upgraded.

I even replaced the “server upgraded” solution files with the old solution files that it didn’t like and it continued to work just fine.

There must be some other files stored somewhere that made it think that it hadn’t been upgraded yet.

This isn’t a great solution, but it works at least.

 

Using Asyncronous Tasks In ASP.NET

ASP.NET has a limited number of threads that it uses to service incoming requests.  Thes threads from the its thread pool, and when its collection of threads are busy, requests have to queue up waiting for an open thread.

But, what happens when you have threads that are blocking waiting for another process to complete?  This could we a database call, or a webservice call, or an IO operation etc.

Well, what happens is that the thread, while doing no real work, is unavailable to service requests.

So, if your database is crunching on some long queries, other simple web requests may be sitting in the queue unable to be handled, even though the webserver CPU is idle.

One solution to this is to use Async pages/methods in ASP.NET 2 or greater.

Async operations allow the thread to be returned back to the thread pool instead of blocking, while some process is executed.

 

There is more than 1 way to do async operations like this from asp.net pages. 

One is to use RegisterAsyncTask and the other to user AddOnPreRenderCompleteAsync as well as declare the page as Async=”true”.

I won’t go into all the details, but AddOnPreRenderCompleteAsync is probably simpler, but you can’t define a timeout, you can’t call it multiple times in parallel, and in the EndAsyncOperation event handler you can’t access things like the httpcontext object.

Here are 2 examples of pages that are asynchronously serving up a PDF document (which is itself served from a page DownloadPDF.aspx, which has a 5 second thread sleep in it to simulate the processing of the report on another server.

Using AddOnPreRenderCompleteAsync:

Imports System.Net
Imports System.IO

Partial Class AsyncServer
    Inherits System.Web.UI.Page

    Dim _request As WebRequest

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        AddOnPreRenderCompleteAsync(New BeginEventHandler(AddressOf BeginAsyncOperation), _
                                    New EndEventHandler(AddressOf EndAsyncOperation))
    End Sub

    Function BeginAsyncOperation(ByVal sender As Object, ByVal e As EventArgs, ByVal cb As AsyncCallback, ByVal state As Object) As IAsyncResult
        _request = WebRequest.Create(HttpContext.Current.Request.Url.Scheme & _
                                     "://" & HttpContext.Current.Request.Url.Authority & _
                                     Page.ResolveUrl("DownloadPDF.aspx"))
        Return _request.BeginGetResponse(cb, state)
    End Function

    Sub EndAsyncOperation(ByVal ar As IAsyncResult)
        Dim reportResponse As WebResponse = _request.EndGetResponse(ar)
        Dim reader As New BinaryReader(reportResponse.GetResponseStream())

        Dim buffer(reportResponse.ContentLength) As Byte
        buffer = reader.ReadBytes(buffer.Length)
        
        Response.Clear()
        Response.ClearHeaders()
        Response.ClearContent()
        Response.ContentType = "Application/pdf"
        Response.BinaryWrite(buffer)
    End Sub

End Class

 

But I prefer to use RegisterAsyncTask.  Now, keep in mind that many operations will already support async versions (webrequests, webservice calls, databases calls, file IO etc), but if there isn’t already built in support for an async call, you can make your own method work in this framework with an async delegate.  Check out the commented code below for how you could do this, but because webrequests already support making the call in an asynchronous fashion, I don’t need to.

Imports System.Net
Imports System.IO

Partial Class RegisterAsyncTaskServer
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Page.AsyncTimeout = New System.TimeSpan(0, 0, 8)
        Dim task As New PageAsyncTask(New BeginEventHandler(AddressOf BeginGetAsyncData), _
                                      New EndEventHandler(AddressOf EndGetAsyncData), _
                                      New EndEventHandler(AddressOf TimeoutGetAsyncData), "task1", True)

        RegisterAsyncTask(task)
    End Sub

    '*************** This is one way to do this if not using an async download method by creating an async delegate
    'Dim taskDelegate As AsyncTaskDelegate
    '' Create delegate.
    'Delegate Sub AsyncTaskDelegate()
    'Private Function BeginGetAsyncData(ByVal src As Object, ByVal args As EventArgs, ByVal cb As AsyncCallback, ByVal state As Object) As IAsyncResult
    '    Dim extraData As New Object
    '    taskDelegate = New AsyncTaskDelegate(AddressOf DownloadReport)
    '    Dim result As IAsyncResult = taskDelegate.BeginInvoke(cb, extraData)
    '    Return result
    'End Function
    'Private Sub DownloadReport()
    'End Sub

    Private reportRequest As WebRequest

    Private Function BeginGetAsyncData(ByVal src As Object, ByVal args As EventArgs, ByVal cb As AsyncCallback, ByVal state As Object) As IAsyncResult
        reportRequest = WebRequest.Create(HttpContext.Current.Request.Url.Scheme & "://" & _
                                          HttpContext.Current.Request.Url.Authority & _
                                          Page.ResolveUrl("DownloadPDF.aspx"))
        Return reportRequest.BeginGetResponse(cb, state)
    End Function


    Private Sub TimeoutGetAsyncData(ByVal ar As IAsyncResult)
        Response.Write("TIMEOUT")
    End Sub

    Private Sub EndGetAsyncData(ByVal ar As IAsyncResult)
        Dim reportResponse As WebResponse = reportRequest.EndGetResponse(ar)
        Dim reader As New BinaryReader(reportResponse.GetResponseStream())

        Dim buffer(reportResponse.ContentLength - 1) As Byte
        buffer = reader.ReadBytes(buffer.Length)

        Response.Clear()
        Response.ClearHeaders()
        Response.ClearContent()
        Response.ContentType = "Application/pdf"
        Response.BinaryWrite(buffer)
        Response.Flush()
    End Sub

End Class

Nice!

Verizon tried to bill me for Quick2Net service

I spent over an hour arguing with people from Verizon about a charge on my bill for my EVDO card.

They charged me another 200 dollars for “minutes” used.  Clearly this is a mistake, as I don’t use the chip embedded in my laptop like others use a cell phone.  It’s impossible actually, seeing as how you hold a mobile phone up to your face and my device is embedded in my laptop :).

At first, they spent 20 minutes telling me that the extra charge was for VOIP calls.  This is a directly quote from the CSR: “For example, you can use Yahoo instant messenger to make VOIP calls where you talking to someone through your computer.”

I continued to argue that they don’t charge for VOIP traffic any differently than normal traffic.

3 times she told me that, yes, in fact they did, and it’s right there in my contract.  I kept asking her to show me where that was in my contract, and of course there was nothing about it.

In fact, Verizon even advertises VOIP as on of the uses of getting an EVDO card and data plan.

Anyway… so eventually they changed their tune and started saying that it was because I was using their Quick2Net network.  I tried to get them to understand that making VOIP calls, and connecting to a different data network are nothing alike, but they continued to act as if they were 1 in the same.

After 45 minutes or so we were no longer arguing about Skype usage and were fully on the topic of the Quick2Net network.  The CSR couldn’t even explain to me WHAT the Quick2Net network was, or HOW I could even connect to this network, IF I WANTED TO!

They had 2 times when they claimed I connected to the Quick2Net network for an extended period.  Both of these times conflicted with my local VZAccessManager logs of when I was connected to the BroadbandAccess Rev-A network, but the CSR didn’t seem to care about the fact that my own logs conflicted with what they were trying to bill me for.

While I was on hold I did some research and found that the Quick2Net network is the ooooooooold data network that Verizon has.  It’s speed is 14.4k, or about 100 times slower than the connection I already pay for.

In fact, when I found this screen shot, I remembered Quick2Net:

This was probably about 5 years ago when this option was available.  As you can see, you used to be able to click on Quick2Net (and it used to be free), but I haven’t had that option available to me for years.

Finally, the CSR set me to her supervisor, who agreed to refund my charge, and setup my account so that I wouldn’t connect to Quick2Net again.

But, not because I never really connected to quick to net, or because it was a billing error on their part, or because if I DID connect, it was through a fault of their software/network/switches.  No, they agreed because I wouldn’t have “benefited” from the Quick2Net services (seeing as how I already pay for a 100x faster connection).  I made a point to let him know that I never connected to this service, but accepted the resolution.

If you are unfortunate as I was, and Verizon tries to bill you for this, good luck.

I didn’t find anything online with people saying they had this same exprience, so I’m posting this in case others run into this same issue and are wondering what happened.

NeatWorks vs Paperport

I bought a cheap version of NeatWorks and downloaded a demo of Paperport from Nuance in an attempt to find a good option for digitizing all my mail.

My experience with NeatWorks isn’t great.  It mostly works, but some problems have cropped up from time to time that make me have some concern.  For example, when I first installed the application it automatically searched for updates: it found one, and I installed the newer version of the app (newer that what was on the CD).

Well, it turned out over the next few days that much of the text that it would OCR would not make it into the search index.  So when you went to search for some keywords nothing would be found.

I contacted support and after walking me through a bunch of stuff, it turned out that there was a much newer version of the app available (but somehow their auto update didn’t find it).  This new version seemed to fix this problem, but I basically had to rescan all my documents.  At that point, it was only a few, but what if I run into another problem after I have a few hundred scanned documents?

Speaking of a few hundred documents, right now I have 50 pages scanned and my database is 300MB.  This is insane!!  Even if you backup your data and compress it it ends up being like 500KB / page.  WAAAAAAY to large.  I guess it really isn’t THAT big of a deal.  I mean if I end up with 5000 pages (100x what I have now) and my database is 30GB, it will really be stupid, but it won’t really be a problem I guess. 

Another concern of mine with NeatWorks is lock-in.  What if I want to move to some other software product in the future?  How can I get my documents out of NeatWorks?  Well, it turns out not very easily.  You can export each document to a PDF, but you have to do it 1 at a time.  If you select multiple documents, it puts them into 1 giant PDF.  This is completely useless.  If you have 5000 pages and you want to start using some other PDF indexing product, it will take you forever to export all those files.  Also, you can only use the software with their scanners.

Also, last night I noticed that some receipt that I had scanned never showed up in my “inbox” (it goes from the Quick Scan to the Inbox).  This has me concerned.  I got no error message or any indication that something didn’t work right.  It just never showed up.

Paperport has some nice pluses on its side.  It uses any scanner (not just 1 like w/ NeatWorks).  It stores all images as PDFs in a folder on your file system so you can manage them as you would any other file.

Reviews for PaperPort were not good, but others claimed the newer service pack fixed a lot of problems.  I did have it lock up on me once, but otherwise it seemed to work. 

The main problem with Paperport is it is trying to do to many things.  NeatWorks is for exactly what I am doing, Paperport is trying to be a fully featured Scanner software product, helping you to manage photos and stuff like that.  The UI is pretty poor also.

Basically though, the only reason I can’t see myself using Paperport is that there is no way to attach and search by a date field.  I don’t care about the date I scan a document (the file created date), I care about the date of the document.  So when I search for Mastercard statements, I can filter out what I want by date.  I didn’t see any way to do this with Paperport.

Then when I went to submit a question to their support team asking about this, I was totally convinced to not buy their product (click for full size):

As many users have commented, it really does look like Paperport WAS a good product which has just morphed into a big, bloated, difficult to use product.

UPDATE: Now Nuance has changed me for the full product.  I’m guessing part of their trial is that they will automatically bill you for the software if you don’t cancel your trial.  Wonderful, I am really glad I didn’t pick Paperport: time to call and demand a refund…. again (they charged me 8 bucks for some BS extended download service on my free trial… these guys suck).