Framework Madness!

And other adventures C# and asp.net …

Archive for January 2009

Async Only – Using the Background Worker with FTPWebRequest (Part 2 – sort of)

with one comment

In the article Async Async – Using BackgroundWorker and WebClient async upload together (Part 1) I covered the use of the BackgroundWorker and planed to use the WebClient to upload files via FTP.

And so it was that WebClient didn’t support timeouts, nor did it error out correctly if the receiving FTP sever didn’t correctly.

When I moved testing from my local test machine to a staging server smaller FTP uploads worked like a charm, but larger files (50 MB) plus sever seemed to complete. So I stopped using System.Net.WebClient for FTP uploads and switched to FTPWebRequest so I could investigate where the hang up was. Here is the code for using FTPWebRequest to upload a file:

Here is what it does:

   1: private void OnExecuteProcess(FtpWebRequest request)
   2: {
   3:    if (request != null)
   4:    {
   5:       
   6:  
   7:        const int bufferLength = 2048;
   8:        byte[] buffer = new byte[bufferLength];
   9:        int count = 0;
  10:        int readBytes = 0;
  11:        Stream requestStream = null;
  12:  
  13:        using (FileStream stream = File.OpenRead(this.Delivery.Source.FilePath))
  14:        {
  15:            requestStream = request.GetRequestStream();           
  16:  
  17:            do
  18:            {
  19:                readBytes = stream.Read(buffer, 0, bufferLength);
  20:                requestStream.Write(buffer, 0, readBytes);
  21:                count += readBytes;
  22:                
  23:            }
  24:            while (readBytes != 0);
  25:  
  26:            this.isWriteComplete = true;
  27:  
  28:        }
  29:  
  30:        //here is were we get hung up and it throws an exception
  31:        requestStream.Close();
  32:       
  33:        //get the response
  34:        request.GetResponse().Close();
  35:  
  36:    }
  37: }

1) Not shown yet – but this method is called inside a try/finally block so it should not bring the process down.

2) A FileStream is opened based on a object level variable. FileStream allows us to copy out portions of the file instead of the whole thing.

3) A RequestStream is opened from FTPWebRequest. This will allow is to pour in data from file stream and send it to the server.

4) A simple Do/While loop is used to transfer file bytes.

5) When the write process is complete is track in a local variable that the write process is completed.

6) We clean up.

So good so far. If the code looks familiar that’s it because it’s from the FtpWebRequest documentation.

But let’s take a look inside two more code blocks. Here is the method that calls OnExcecuteProcess:

   1: private void OnExecute()
   2: {
   3:     this.Initalize();
   4:  
   5:     FtpWebRequest request = null;
   6:  
   7:     try
   8:     {
   9:        
  10:  
  11:         //build the request
  12:         request = (FtpWebRequest)WebRequest.Create(this.Location.Uri);
  13:         
  14:         request.Method = WebRequestMethods.Ftp.UploadFile;
  15:  
  16:         //build the credentials
  17:         request.Credentials = new NetworkCredential(this.Delivery.Target.Username, this.Delivery.Target.Password);
  18:  
  19:         request.Timeout = 30000;
  20:  
  21:         OnExecuteProcess(request);
  22:  
  23:  
  24:     }
  25:     catch (Exception ex)
  26:     {
  27:        
  28:  
  29:         try
  30:         {
  31:             if (request != null)
  32:             {
  33:                 request.Abort();
  34:             }
  35:         }
  36:         finally
  37:         {
  38:             this.error = ex;
  39:             this.LogProgress(ex.GetPrimary().Message);
  40:         }
  41:  
  42:         
  43:  
  44:     }
  45:     finally
  46:     {
  47:         this.IsComplete = true;
  48:  
  49:         this.OnUploadComplete();
  50:     }
  51: }

Nothing really dramatic. We build the request, set the method, credentials and timeout and pass to OnExecuteProcess. The ‘catch’ block contains a ‘request.Abort’ call and logs the exception. The ‘finally’ block the IsComplete property and calls OnUploadComplete, which triggers a corresponding event.

But here is where we compensate for the failed request completion or response in the Error property.

   1: private Exception error;
   2:  
   3: public Exception Error
   4: {
   5:    get
   6:    {
   7:        if (this.isWriteComplete)
   8:        {
   9:            return null;
  10:        }
  11:  
  12:        return error;
  13:    }
  14: }

In the first code block I set isWriteComplete to true after writing my bytes. Here is where I am using the isWriteComplete property to control error returns.If the logging code sees an error it logs a non-download, so this code avoids returning an error if all the bytes were written to the response stream.

Now as I am writing here I am thinking it’s probably better to return an IsWriteComplete property along with IsComplete, always return the exception, and pass along the logic to the logging tool. I’ll try that and get back with you.

Advertisements

Written by Lynn Eriksen

January 19, 2009 at 10:22 pm

Posted in Uncategorized

Stick that Footer – No, really IE, I mean it!

leave a comment »

I was doing layout for a revision of Christwebs.com today and I was following a fairly well established pattern of using CSS to absolutely position a footer at the bottom of the page – always and regardless of page length. In the process of trying to get the CSS to work I stumbled on a great, concise tutorial on how to do this. Followed it all, again, and I got it working in Firefox and Safari but sure enough I had trouble with IE 7.

Well, I think I found a solution. The IE7.js script does a good job of fixing up IE 6 difficulties and making it work similar to IE 7. But one thing I also remembered is that there is an IE8.js script (here is the link to both on Google Code) that can fix up issues with IE 7. Sure enough, attaching the the IE8.js script fixed it up nicely. No complaints here.

Written by Lynn Eriksen

January 16, 2009 at 7:55 pm

Posted in Uncategorized

Tagged with ,

In My Minds Eye …

leave a comment »

Yep. Some people think it maybe all an illusion. It would be interesting if so.

http://www.newscientist.com/article/mg20126911.300-our-world-may-be-a-giant-hologram.html?full=true

Written by Lynn Eriksen

January 16, 2009 at 11:20 am

Posted in Uncategorized

Tagged with

MySql Entity Framework Support Delayed

with one comment

Looks like we’ll have to wait a bit longer for the delayed Connector/net 6.0 with EF support. Looks like Sun is having ‘issues’ with the SQL generator and a rewrite for that part of the engine is underway.

http://forums.mysql.com/read.php?38,235788,241111#msg-241111

Written by Lynn Eriksen

January 16, 2009 at 10:57 am

Posted in Uncategorized

Tagged with

Light Columns Due to Ice Crystals?

leave a comment »

Written by Lynn Eriksen

January 15, 2009 at 1:33 pm

Posted in Uncategorized

Tagged with

Async Async – Using BackgroundWorker and WebClient async upload together (Part 1)

with 4 comments

Updated 1/19/2009

The discussion on using BackgroundWorker here is good but I had to abandon the use of the WebClient class inside the upload object.

 

Doing async with the BackgroundWorker class (System.ComponentModel) is easy, but when I realized that async could also be done with the WebClient class (System.net) while the BackgroundWorker is executing I had to give it a try so that I could support cancelation. It works, but you have to follow the BackgroundWorker async pattern carefully.

In my case I created a Delivery class that has the responsibility of setting up the BackgroundWorker, staging ftp execution, and clean up. I have an Upload object that manages the async FTP upload separately . This Upload object  is created when Delivery.Execute is called and then passed along to the BackgroundWorker.DoWork event hander, named InitDelivery, for execution. Here’s the code for InitDelivery:

   1: private void InitDelivery(object sender, DoWorkEventArgs e)
   2: {
   3:    if (e.Argument as FTPUpload != null)
   4:    {
   5:        var Upload = e.Argument as FTPUpload;
   6:  
   7:        this.Upload = Upload;
   8:  
   9:        Upload.ExecuteAsync();
  10:  
  11:        //wait here for upload to complete
  12:        while (Upload.IsBusy)
  13:        {
  14:              Thread.Sleep(10);
  15:        }
  16:    }
  17:  
  18:  
  19:  
  20:    e.Result = e.Argument;
  21: }

Here is how it works:

1) The Upload object is retrieved from the e.Argument.

2) The Upload object is passed to a local field so that it’s internal async operation can be canceled if need be.

3) The method Upload.ExecuteAsync is called.

4) Next we wait for the ‘while(Upload.IsBusy)’ to compete. But you might ask why I am doing this if I am using an async in the Upload object?  Here are the reasons:

  • The BackgroundWorker is designed for managing long running, synchronous tasks so we need to mimic that pattern inside the BackgroundWorker.DoWork  event handler.
  • The Upload.IsBusy state is always set to false when the internal async operation finishes regardless of completion, cancelation, or exception.
  • I need to use state from the Upload object in the BackgroundWorker.RunWorkerCompleted event handler.

5) The Upload object is passed to e.Result and the event handler exits.

 

The BackgroundWorker.RunWorkerCompleted event is wired to DeliveryFinish. Here is the code:

   1: private void DeliveryFinish(object sender, RunWorkerCompletedEventArgs e)
   2: {
   3:    try
   4:    {
   5:  
   6:        //set the error
   7:        this.Error = e.Error;
   8:  
   9:        var Upload = e.Result as Upload;
  10:  
  11:        if (Upload != null)
  12:        {
  13:            if (this.Error == null && Upload.Error != null)
  14:            {
  15:                this.Error = Upload.Error;
  16:            }
  17:  
  18:             // perform logging and clean up here
  19:        }
  20:  
  21:        
  22:    }
  23:    finally
  24:    {
  25:        //set iscompleted
  26:        this.IsFinsihed = true;
  27:    }
  28:  }

 

Here is how it works:

1) The Delivery.Error property is set from e.Error and the Upload object is retrieved from e.Result.

2) If the Upload object has an error then it is forwarded to the Delivery.Error property.

3) Perform any logging and clean up as necessary.

4) The Try/Finally block ensures that Delivery.IsFinished is always set to true.

 

Update 2009-01-16

Looks like the ‘Upload.IsBusy’ thread really hammers the processor. To remove that I’ve added a Thread.Sleep call that really dampens things down, and it does keep the transfer working.

 

That’s it for Part 1. In Part 2 I’ll look at the Upload object and cover a few highlights. Here is the link:

https://leriksen71.wordpress.com/2009/01/19/async-only-using-the-background-worker-with-ftpwebrequest-part-2-sort-of/

Written by Lynn Eriksen

January 15, 2009 at 11:01 am

Posted in Uncategorized

Tagged with ,

Windows 7 – Live Mesh Update

leave a comment »

Looks like my problems with Aero glass going in and out were due to Live Mesh. Got an update last night and now the only time glass turns off is when using Remote Desktop.

Written by Lynn Eriksen

January 15, 2009 at 10:10 am

Posted in Uncategorized