views:

32

answers:

2

I have a SilverLight button that gets a comment from a text box to be saved in my database and then closes the window.

SilverLight:

Task task = new Task();
private void saveChangeBtn_Click(object sender, RoutedEventArgs e)
{
    string commentTxtBxValue = commentTxtBx.Text;
    task.SaveComment(commentTxtBx.Text);
    commentTxtBx.Text = commentTxtBxValue;

    HtmlPage.Window.Invoke("closeWindow", null);
}

The SilverLight calls SaveComment() in the model of my SilverLight project which creates a URI and, using this URI, it sends the comment text to my MVC controller with UploadStringAsync().

Model Code:

public void SaveComment(string Comment)    
{    
    // Create post string    
    StringBuilder postData = new StringBuilder();    
    postData.AppendFormat("?{0}={1}", "id", this.PageBreakId);    
    postData.AppendFormat("&{0}={1}", "comment", Comment);    


    string dataString = postData.ToString();    
    byte[] data = Encoding.UTF8.GetBytes(dataString);    

    // Configure client    
    WebClient client = new WebClient();    
    client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);    
    client.UploadStringCompleted += new UploadStringCompletedEventHandler(client_UploadStringCompleted);    

    string baseUri = HtmlPage.Document.DocumentUri.ToString().ToLower();    
    baseUri = baseUri.Substring(0, baseUri.IndexOf("currentPage"));    

    Uri uri = new Uri(baseUri + "SaveComment", UriKind.Absolute);    

    try    
    {    
        // Start upload         
        client.UploadStringAsync(uri, dataString);    
    }    
    catch (Exception e)    
    {    
        System.Diagnostics.Debug.WriteLine(e.Message);    
    }    
}   

Finally, my MVC Controller saves it to the database.

MVC Controller:

[AcceptVerbs(HttpVerbs.Post)]    
 public ActionResult SaveComment()    
 {    
    //Save to Database    
 }

My problem is that, it seems, my SilverLight code HtmlPage.Window.Invoke("closeWindow", null); closes the page and ends code execution before it has a chance to finish. If I put a break point on my MVC controller it will only sometimes get triggered. I've noticed that FireFox will nearly always hit it but IE8 will almost never hit it.

What can I do to ensure my code will finish before I close the page?

Thank you,

Aaron

A: 

Your `WebClient.UploadStringAsync' is a parallel method. Once your code hits there, it moves on to the rest of the program, which is why it may hit the close window code before it gets a chance to execute its internal code.

Resolution

  1. In you Task class, implement an event and call it inside your UploadStringCompleted callback. Then listen when this event is triggered inside your main code and fire the close window code.
  2. Another way to do this is to just put your close window code inside your UploadStringCompleted (may be bad design) in the Task class.
Shawn Mclean
dont you mean the UploadStringCompleted event?
almog.ori
A: 

As is you may/maynot have enough execution time to complete the upload (because its async therefore execution continues after execution reaches UploadStringAsync instead of waiting and the routine exits)

msdn has this to say on WebClient.UploadStringAsync ..

Uploads the specified string to the specified resource. These methods do not block the calling thread.

there is an event for UploadStringAsync to determine when the upload is finished, its the WebClient.UploadStringCompleted Event

msdn has this to say on WebClient.UploadStringCompleted Event

Occurs when an asynchronous string-upload operation completes.

in which you could close the page. ie call the following within your event handler.

HtmlPage.Window.Invoke("closeWindow", null);
almog.ori