我的代码是否以正确的顺序执行?

时间:2019-06-20 15:37:26

标签: c# xamarin

我有以下代码,我希望它以正确的顺序执行,但是我不确定我是否正确使用“ await”,以便以正确的顺序执行。

正确的顺序应为:

1)调用GetTiltleData并获取CurrentCatalogVersion。

2)调用GetCatalogData获取将要购买的商品的ItemID。

3)致电MakePurchase购买该物品。

4)调用GetInventoryList获取玩家当前(购买后)的库存。

我使用的等待正确吗?我的代码执行顺序正确吗?还是有可能以错误的顺序执行代码?

例如,GetCatalogData()的代码是否可能?在CurrentCatalogVersion = result.Result.Data [“ Catalogversion”];之前执行?

string CurrentCatalogVersion = "";
string ItemID = "";
int CurrentAmount = 0;

GetTiltleData();
GetCatalogData();

public async void GetTiltleData()
{
    await ClientGetTitleData();
}

private async Task ClientGetTitleData()
{
    var result = await PlayFabClientAPI.GetTitleDataAsync(new GetTitleDataRequest());

    if (result.Result.Data == null || !result.Result.Data.ContainsKey("Catalogversion"))
        Console.WriteLine(result.Error.GenerateErrorReport());
    else
        CurrentCatalogVersion = result.Result.Data["Catalogversion"];
}

public async void GetCatalogData()
{
    await GetCatalog();
}

private async Task GetCatalog()
{
    var result = await PlayFabClientAPI.GetCatalogItemsAsync(new GetCatalogItemsRequest()
    {
        CatalogVersion = CurrentCatalogVersion
    });

    foreach (var entry in result.Result.Catalog)
    {
        //For example, if you want to purchase a sword
        if (entry.DisplayName == "Sword")
            ItemID = entry.ItemId;
    }

    if (result.Error != null)
    {
        Console.WriteLine(result.Error.GenerateErrorReport());
    }
    else
    {
        Console.WriteLine("Listed items successful!");
        await MakePurchase(ItemID);
    }
}


private async Task MakePurchase(string itemid)
{
    var result = await PlayFabClientAPI.PurchaseItemAsync(new PurchaseItemRequest()
    {
        CatalogVersion = CurrentCatalogVersion,
        ItemId = ItemID,
        Price = 100,
        VirtualCurrency = "GO"
    });

    if (result.Error != null)
    {
        Console.WriteLine(result.Error.GenerateErrorReport());
    }
    else
    {
        Console.WriteLine("Purchase successful!");
        await GetInventoryList();
    }
}

private async Task GetInventoryList()
{
    var result = await PlayFabClientAPI.GetUserInventoryAsync(new GetUserInventoryRequest());
    //Get the current amount of the player's virtual currency after the purchase
    CurrentAmount = result.Result.VirtualCurrency["GO"];

    foreach (var entry in result.Result.Inventory)
    {
        //Get a list with the player's items after the purchase
        Console.WriteLine($"{entry.DisplayName} {entry.UnitPrice} {entry.ItemId} {entry.ItemInstanceId}");
      ...
    }

    if (result.Error != null)
    {
        // Handle error if any
        Console.WriteLine(result.Error.GenerateErrorReport());
    }
    else
    {
        Console.WriteLine("Got current inventory");
    }
}

1 个答案:

答案 0 :(得分:0)

  

例如,GetCatalogData()的代码是否可能?在CurrentCatalogVersion = result.Result.Data [“ Catalogversion”];之前执行?

是的,绝对。

这是您的呼叫代码:

...
GetTiltleData();
GetCatalogData();

这些是异步方法,但是在继续下一条指令之前,您不必等待它们的结果。这意味着这两种方法都是即发即弃线程。

这意味着您有比赛条件。从字面上看,您有2个线程争先恐后地完成他们的方法。您无法保证哪一个先完成,或者CPU如何确定其指令的优先级。由于您是如何调用这些方法的,因此实际上您已经告诉计算机您不在意事件的结果。

确保一种方法在另一种方法开始之前完成的最快方法是await。正如Igor所说,如果要使用异步方法,则应该在整个调用堆栈上下使用async / await

string CurrentCatalogVersion = "";
string ItemID = "";
int CurrentAmount = 0;

await GetTiltleData(); // adding "await" to these 2 lines
await GetCatalogData();

此外,请不要在方法签名中使用async void。您应该改用async Task。参见async/await - when to return a Task vs void?