• 网络——异步搜索网络会话


    问题

    一些网络操作,诸如下载玩家配置或搜索可用的会话,会花费大量的时间。前面的教程中使用的是最简单的设置,这些操作会使程序暂停直至操作完成,这段时间中你想让玩家知道操作的信息!

    解决方案

    XNA为几乎所有需要时间完成的网络操作提供了异步选择。例如,NetworkSession. Find 方法的异步操作对应NetworkSession. BeginFind方法。

    在异步操作的开始,XNA会创建第二个线程用于这个操作,让这个操作可以与主程序并行处理。这样做的优点是,你的主程序只需初始化异步操作,然后可以继续自己的处理。这让你可以向玩家提供任何运行在第二个线程中的异步操作的信息。

    一旦异步操作完成,结果会传递到你指定的方法中,让你可以处理异步操作产生的结果。

    工作原理

    这个教程会解释如何使用NetworkSession.BeginFind方法,XNA中的其他的异步操作工作原理是相同的。

    这个教程是教程8-3的异步版本,在那个教程中,程序开始处于SignIn状态并依次进入SearchSession, CreateSession和InSession状态。在这个教程中,你将添加一个Searching状态,当操作在后台运行时可以向用户提供信息:

    public enum GameState
    ...{
        SignIn, 
        SearchSession,
        Searching, 
        CreateSession, 
        InSession
    }
    开始异步操作

    SearchSession状态很容易,因为它要做的只是初始化异步操作:

    case GameState.SearchSession:
    ...{
        NetworkSession.BeginFind(NetworkSessionType.SystemLink, 2, null, EndAsynchSearch, null);
        log.Add("ASynch search started - proceed to Searching"); 
        log.Add("Searching");
        currentGameState = GameState.Searching;
    }
    break;

    NetworkSession.BeginFind方法会导致在后台创建第二个线程,这个线程与主程序并行进行搜索操作,这样带来的好处是主程序在运行到NetworkSession.BeginFind时无需等待(而使用NetworkSession.Find方法时需要),可以立即进入到Searching状态。

    NetworkSession.BeginFind方法需要五个参数。前三个和NetworkSession. Find方法是相同的,可见教程8-3的解释。

    要理解第四个参数,我需要解释当后台的搜索操作结束后会发生什么。第二个线程会调用你的方法之一并将它传递到结果。这意味着你必须指定应该调用哪个方法,这可以通过使用第四个参数做到。在本例中,当第二个线程结束后你指定它调用EndAsynchSearch方法,这个方法后面就会讲到。

    最后一个参数让你识别异步操作,当在同一时间有多个异步操作的情况中这是很有用的。可见教程1—9看一下这个参数的例子。

    在此期间. . .

    当搜索在后台进行时,你可以自由地在Searching状态中做任何其他操作。在这个简单的例子中,每次调用Update方法时, 会在显示在屏幕的文字后面加上一个”.”。

    case GameState.Searching: 
    ...{
        log[log.Count - 1] +=”.” 
    }
    break;
    NetworkSessions.EndFind

    当运行在后台的第二个线程结束异步搜索后,它会调用在NetworkSession. BeginFind方法中第四个参数指定的方法。在前面的代码中,我指定的是EndAsynchSearch方法,具体代码如下,看起来比较复杂,但主要部分来自于前一个教程的SearchSession状态中的代码:

    private void EndAsynchSearch(IAsyncResult result)
    ...{
        AvailableNetworkSessionCollection activeSessions = NetworkSession.EndFind(result);
        if (activeSessions.Count == 0)
        ...{
            currentGameState = GameState.CreateSession;
            log.Add("No active sessions found - proceed to CreateSession");
        }
        else
        ...{
            AvailableNetworkSession sessionToJoin = activeSessions[0]; 
            networkSession = NetworkSession.Join(sessionToJoin);
    
            string myString = "Joined session hosted by " + sessionToJoin.HostGamertag; 
            myString += " with " + sessionToJoin.CurrentGamerCount.ToString() + " players";
            myString += " and " + sessionToJoin.OpenPublicGamerSlots.ToString() + " open player slots.";
            log.Add(myString);
    
            HookSessionEvents();
            currentGameState = GameState.InSession;
        }
    }

    这个方法将异步操作的结果作为参数。

    对每个开始一个异步操作的方法,你都会找到一个方法可以处理它的结果。本例中开始异步操作的是NetworkSession.BeginFind方法,你可以将结果传递到NetworkSession.EndFind方法,这个方法将结果放在一个AvailableNetworkSessionCollection对象中。接下去的操作就和前一个教程一模一样了。

    代码

    下面是Update方法中的switch代码块,这个代码让程序从SignIn状态移动到SearchSession和Searching状态。EndAsynchSearch方法决定是否移动到CreateSession或 InSession状态。

    switch (currentGameState)
    ...{
        case GameState.SignIn:
        ...{
            if (Gamer.SignedInGamers.Count < 1)
            ...{
                Guide.ShowSignIn(1, false);
                log.Add("Opened User SignIn Interface");
                currentGameState = GameState.SearchSession; 
                log.Add(Gamer.SignedInGamers[0].Gamertag + " logged in - proceed to SearchSession");
            }
        }
        break;
        case GameState.SearchSession:
        ...{
            NetworkSession.BeginFind(NetworkSessionType.SystemLink, 2, null, EndAsynchSearch, null);
            log.Add("ASynch search started - proceed to Searching");
            log.Add("Searching");
            currentGameState = GameState.Searching;
        }
        break;
        case GameState.Searching:
    ...    {
            log[log.Count - 1] += ".";
        }
        break;
        case GameState.CreateSession:
    ...    {
            networkSession = NetworkSession.Create(NetworkSessionType.SystemLink,4, 16);
            networkSession.AllowHostMigration = true;
            networkSession.AllowJoinInProgress = false;
            log.Add("New session created");
    
            HookSessionEvents();
            currentGameState = GameState.InSession;
        }
        break;
        case GameState.InSession:
        ...{
            networkSession.Update();
        }
        break; 
    }
  • 相关阅读:
    HipHop PHP & HHVM资料收集
    [转]Linux系统下如何查看及修改文件读写权限
    [转]Console命令详解,让调试js代码变得更简单
    js中(function(){…})()立即执行函数写法理解
    [Link]NoSQL
    [转]Hadoop Hive sql语法详解
    [转]redis配置文件redis.conf的详细说明
    【转】各种 NoSQL 的比较
    [转]MongoDB基本使用
    【转】windows下mongodb安装与使用整理
  • 原文地址:https://www.cnblogs.com/AlexCheng/p/2120082.html
Copyright © 2020-2023  润新知