O
Omatase
I'm posting this here although I have already posted it on the MSDN
forums because noone seems to visit those forums.
Thanks for any help you can give!
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
forums because noone seems to visit those forums.
Thanks for any help you can give!
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