2017-05-08 101 views
0
public class Item 
{ 
    public string typeid; 
    public string typename; 
    public string minsell; 
    public string maxbuy; 
    public string systemid; 
    public string systemname; 
    public Item(JArray jItem) 
    { 
     typeid = jItem[0]["all"]["forQuery"]["types"][0].ToString(); 
     minsell = jItem[0]["sell"]["min"].ToString(); 
     maxbuy = jItem[0]["buy"]["max"].ToString(); 
     systemid = jItem[0]["all"]["forQuery"]["systems"][0].ToString(); 
     GetAsync(); 
     Console.WriteLine("inside the constructor" + typename + " " + systemname); 
    } 
    public async void GetAsync() 
    { 
     typename = await ESIGenericRequests.GetTypeNameAsString(typeid); 
     systemname = await ESIGenericRequests.GetSystemNameAsString(systemid); 
     Console.WriteLine("inside the async void method" + typename + " " + systemname); 
    } 
} 

我正在从json数组对象实例化一个项目,但在那个json数组中没有我想要的一些值,我可以通过一个异步API请求。由于我不能在我的同步构造函数中调用异步方法,所以我通常会做(我在代码中的不同位置完成了同样的事情,并且工作正常),这是一个为我实现的异步无效GetAsync()方法。问题是这些值不会在异步方法之外改变。这是它登出:从构造函数调用私有方法不会改变变量的值

inside the constructor 

inside the async void methodBarghest Jita 

编辑:这可行,几乎是同样的事情:

public class Character 
{ 
    public string char_id; 
    public string name; 
    public string corporation_id; 
    public string corporation_name; 
    public string alliance_id = null; 
    public string alliance_name; 
    ... 
    public Character(JObject _Character, Killboard _Killboard) 
    { 
     ... 
     GetAsync(); 

    } 
    private async void GetAsync() 
    { 
     char_id = await ESIGenericRequests.ESISearch(name, "character"); 
     corporation_name = await ESIGenericRequests.GetCorpNameAsString(corporation_id); 
     if (alliance_id != null) alliance_name = await ESIGenericRequests.GetAllianceNameAsString(alliance_id); 
    } 

} 
+0

实例请尽量不要张贴文字的屏幕截图。对于阅读你的问题的人来说这不是很友好。 –

+0

他们*将*改变 - 但您并未等待异步操作完成。所以你会在未来某个时候看到这些变化。这就像打在网页浏览器地址栏上的回报,然后立即截图 - 这不太可能显示您要加载的网站... –

+0

由于某种原因,基本上相同的代码工作基本相同: –

回答

0

的异步调用完成之前,您正在登录。您可以使用异步静态工厂方法,方法是在构造函数被调用后将构造函数设置为非公共,并将异步调用移入工厂,或者添加客户程序构建后必须调用的公共异步初始化方法。例如:

private async Task<Item> InitializeAsync() 
{ 
    typename = await ESIGenericRequests.GetTypeNameAsString(typeid); 
    systemname = await ESIGenericRequests.GetSystemNameAsString(systemid); 
    return this; 
} 

public static Task<Item> CreateAsync() 
{ 
    var ret = new Item(); 
    return ret.InitializeAsync(); 
} 

另外,如果你想在异步调用块,你可以得到awaiter:

public void Get() 
{ 
    typename = ESIGenericRequests.GetTypeNameAsString(typeid).GetAwaiter().GetResult(); 
    systemname = ESIGenericRequests.GetSystemNameAsString(systemid).GetAwaiter().GetResult(); 
    Console.WriteLine("inside the formerly-async void method" + typename + " " + systemname); 
} 

看看斯蒂芬·克利里的博客帖子上的图案为dealing with async and constructors

+0

这解决了这个问题,谢谢!编辑:我没有注意到你发布了代码,直到我编辑并发布我的,谢谢。 –

+0

很高兴听到它! –

0

this后:

public static async Task<Item> CreateAsync(JArray jItem) 
    { 
     var ret = new Item(jItem); 
     ret.typename = await ESIGenericRequests.GetTypeNameAsString(ret.typeid); 
     ret.systemname = await ESIGenericRequests.GetSystemNameAsString(ret.systemid); 
     return ret; 
    } 

我加入这个方法我的课,我现在有了这个

Item item = await Item.CreateAsync(jItem); 
相关问题