首页 > 解决方案 > 我的代码是否以正确的顺序执行?

问题描述

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

正确的顺序应该是:

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");
    }
}

标签: c#xamarin

解决方案


例如,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 - 何时返回 Task vs void?.


推荐阅读