locked
WCF "Begin" call is *sometimes* blocking ? RRS feed

  • Question

  • I have a question mark at the end of the title because I can't quite tell what is happening, but although I have Begin* and End* calls littered throughout my code (I am doing a Silverlight app) I am only having an issue with one call in particular.

    The problem I am having is I call BeginCreateTeam on my WCF service and wait for the AnonymousMethod that I provided in the AsyncCallback to execute. While I am waiting I execute this code:

    while(createTeamSuccessful == null)
    {
        Thread.Sleep(1000);
    }

    createTeamSuccessful is a bool that is populated when the AsyncCallback AnonymousMethod is executed.

    Although I use this pattern all over the place in my Silverlight code, it isn't working in this case for some reason. Below is a more complete picture of the code I am using.

    _popup is a class that displays some UI elements. When the UI element is closed, OnPopupClosed is called (shown below this code element)

    _popup = new InputPopup(CherubGameReference);

    _popup.OnPopupClosed += ((a) =>
    {
    if (!string.IsNullOrEmpty(a.Trim()))
    {
    _teamName = a.Trim();
    if(createTeam(_teamName))
    {
    CherubGameReference.RefreshAccountDetails();
    CherubGameReference.ShowNotification(string.Format("New team ({0}) created.", _teamName));
    Drop(GameStateData.ManageTeamsMenu, null);
    }
    else {
    _finishButton.Enabled = true;
    Form.Active = true;
    }
    }
    else {
    _finishButton.Enabled = true;
    Form.Active = true;
    }
    });

    _finishButton.OnClick += ((a) =>
    {
    _finishButton.Enabled = false;
    Form.Active = false;


    _popup.ShowPopup("Please enter a name for your new team");
    });
    ok is a button in the popup UI element.

    ok.OnClick += ((a) =>
    {
    if(OnPopupClosed != null)
    {
    OnPopupClosed.Invoke(_textBox.Text);
    Hide();
    }
    });
    here is the "createTeam" method for completeness, a portion of this code is already shown above

    private bool createTeam(string teamName)
    {
    bool? createTeamSuccessful = null;
    NetworkAbstractionLayer.CreateTeam((from a in _selectedCharacters
    select a).ToList(), teamName, (a) => { createTeamSuccessful = a; });
    while (createTeamSuccessful == null)
    {
    Thread.Sleep(1000);
    }
    return createTeamSuccessful.GetValueOrDefault();
    }
    "NetworkAbstractionLayer" is a static class that keeps a single instance to the WCF proxy open and available to the entire Silverlight application and is responsible for handing the call off to the layer that calls BeginCreateTeam and EndCreateTeam.

    I have tried removing the static class as a step in the process without success.

    What I see happening is the Silverlight app hangs when the createTeam method is called and that the code never leaves the while loop in the immediately above code block. If I manually move execution below the while loop then the AsyncCallback code is magically called!

    One anomaly that I see occurring that doesn't look right is when I look at the "Threads" window in VS when I am debugging in the sections of code where I am doing any of the following:

        * Invoking the OnPopupClosed event
        * Handling the OnPopupClosed event
        * Executing the BeginCreateTeam WCF call
        * Handling the BeginCreateTeam AsyncCallback

    It shows the current executing thread is "Main Thread". Since the above items were all within an AnonymousMethod I expected to see the thread executing on a thread other than "Main Thread" which is how it seems to work everywhere else I am using this asynchronous pattern.

    Appreciate any help!

    --edit 01/09/10 8:26 AM--

    Here is some more information I just learned about the problem:

    Here is the actual code where Begin and End are handled:
    public void CreateTeam(List<Character> characters, string teamName, Action<bool> createTeamCallback)
    {
        _client.BeginCreateTeam(SessionManager.SessionId, characters.ToArray(), teamName, ((a) =>
        {
            GameResponse returnedFromServer = ((ServiceClient)a.AsyncState).EndCreateTeam(a);
    
            if (createTeamCallback != null && returnedFromServer != null && returnedFromServer.ReturnValue != null)
            {
                createTeamCallback.Invoke((bool)returnedFromServer.ReturnValue);
            }
    
        }), _client);
    }
    
    I just discovered after putting a breakpoint in my WCF server code that although the debugger steps passed this block of code before entering my while loop (I see the yellow highlight the entire block in this method and then continue on). The CreateTeamMethod doesn't actually execute on the server side unless I manually (in the debugger) exit the while loop. ... Strange
    • Edited by omatase1 Saturday, January 9, 2010 3:43 PM code is impossible to read!
    Saturday, January 9, 2010 6:11 AM

Answers

  • Are you creating a new thread to do these calls? Or is this all happening on the main thread? I would suppose the later since you say you whole apps hangs when you do this call.

    Note that HTTP network calls in Silverlight happens on the UI thread. When you block the thread, you are effectively stopping the network call to be made at the same time, explaining the behavior you see when you force a step through out of the while loop.

    A solution would be to make the call on a different thread. You would then block on this thread to wait for your operation to complete, and you would callback on the main thread when you get the response.
    Christopher Scrosati, Software Design Engineer, WCF Silverlight, Microsoft Corp.
    • Proposed as answer by Carlos Figueira Tuesday, January 12, 2010 9:59 PM
    • Marked as answer by Riquel_Dong Thursday, January 14, 2010 2:12 AM
    Monday, January 11, 2010 5:00 PM