[翻译]XNA 3.0 Game Programming Recipes之fiftyseven


PS:自己翻译的,转载请著明出处
                                                            8-5 异步的收寻网络会话
问题
                                   某些网络操作,例如下载一个玩家的个人资料或者收寻可以用的会话,要花费不少的时间。使用在前面的章节中使用非常便捷的设置方法,这些操作将使你的程序迟缓直到操作全部完成,同时你又想去告诉用户游戏的进度!
解决方案
                                   XNA为几乎所有的网络方法提供了一个异步的选择,它要求一些时间去完成。NetworkSession.Find方法的异步部分,例如,是NetworkSession.BeginFind方法。
                                   在一个异步操作的开始,XNA将退出第二个线程在它的操作上被执行,允许它与你的主程序同时运行。作为一个优势,你的主程序将只启动异步操作,并且马上接着执行主程序。这允许你有任何你喜欢的信息去提供给用户,同时这个异步操作在第二个线程中运行。
                                   一旦异步操作已经完成,这个结果将会被传到一个方法中,这个方法是你指定的。这个允许你通过异步操作去处理被收集的结果。
它是如何工作的
                                  这节将解释如何去使用这个NetworkSession.BeginFind方法。其他的异步操作在XNA都遵循同样的原则。
                                  这节是8-3的异步版本。在那节里,你的程序在SignIn状态中开始,并且审查这个SearchSession,CreateSession,和InSession状态。在这节里,你将会添加Searching状态,它允许你去提供给用户信息同时这个操作是在后台运行的。
1 public enum GameState{SignIn,SearchSession,Searching,CreateSession,InSession}

Starting the Asynchronous Operation(开始异步操作)
                                  这个SearchSession状态变得非常的容易,因为所有它能做的是启动异步操作:
1 case GameState.SearchSession:
2 {
3      NetworkSession.BeginFind(NetworkSessionType.SystemLink,2,null,EndAsynchSearch,null);
4      log.Add("ASynch search started-proceed to Searching");
5      log.Add("Searching");
6      currentGameState=GameState.Searching;
7 }
8 break;

                                 NetworkSession.BeginFind方法将导致在后台中一个第二个线程被创建。这个线程将执行寻找与你的主程序同时进行。作为一个好处,你程序NetworkSession.BeginFine与它的NetworkSession.Find方法不用一致完成。相反,它立即接着到Searching状态。
                                 NetworkSession.BeginFind方法要求五个参数。这头三个参数是与NetworkSession.Find的方法相同的,如8-3节所描述的。
                                 为了理解第四个参数,我们将讨论当在后台寻找完了后发生了什么。第二个线程将调用你的其中之一的方法,并且传递它到结果中。意思是你不得不指定哪个方法应该被调用,使用第四个参数它可以被实现。在这个例子中,你引导第二个线程去调用EndAsynchSearch方法,当它完成时,你可以在下面找到它。
                                 最后的参数允许你去确定异步操作,在你有多个异步操作同时运行时的情况下,它是有益的。参看1-9节。

In the Meantime . . .
                                 虽然收寻是在后台运行的,在Searching状态中你可以自由的去做任何你想要的事情。在这个样列中,每一次Update方法被调用,一个点就会被添加到最后一行里,然后打印到屏幕上:

1 case GameState.Searching:
2 {
3     log[log.Count-1]+=".";
4 }
5 break;


NetworkSessions.EndFind
                                当第二个线程,它运行在后台中,已经完成它的异步收寻,它将调用这个你指定的方法作为第四个参数在NetworkSession.BeginFind方法中。在前面的代码中,我指定EndAsynchSearch方法,你可以在这里找到它。它看起来完成了。但是主要的部分从前面章节的SearchSession状态中被接受。多数异步回调方法期待一个IAsyncResult对象,它包含非常有用的值通过正在初始化的方法(BeginFind)。参看1-9节的例子,那里有这个IAsyncResult对象被询问。

 1 private void EndAsynchSearch(IAsyncResult result)
 2 {
 3     AvailableNetworkSessionCollection activeSessions=NetworkSession.EndFind(result);
 4     if(activeSessions.Count==0)
 5     {
 6         currentGameState=GameState.CreateSession;
 7         log.Add("No active sessions found-proceed to CreateSession");
 8     }
 9     else
10     {
11         AvailableNetworkSession sessionToJoin=activeSessions[0];
12         networkSession=NetworkSession.Join(sessionToJoin);
13         string myString="Joined session hosted by"+sessionToJoin.HostGamertag;
14         myString+="with"+sessionToJoin.CurrentGamerCount.ToString()+"players";
15         myString+="and"+sessionToJoin.OpenPublicGamerSlots.ToString()+"open player slots";
16         log.Add(myString);
17         HookSessionEvents();
18         currentGameState=GameState.InSession;
19     }
20 }

                                 这个方法接收来自异步操作的这个结果,它作为参数。
                                 每个方法开始一个异步的操作,你可以找到一个方法,它有处理它的结果的能力。在这个NetworkSession.BeginFind方法的情况下,你可以传递结果到NetworkSession.EndFind方法中,它将处理这个结果成一个AvailableNetworkSessionCollection对象。从这里开始,同样保持和前面章节一样。

代码
                   (略)
源代码:http://shiba.hpe.cn/jiaoyanzu/WULI/soft/xna.aspx?classId=4
(完)

原文地址:https://www.cnblogs.com/315358525/p/1561657.html