2014-06-07 65 views
-4

在我的游戏中,我注意到一些冻结,因为AdComponent试图从互联网上下载一个新的广告来绘制在我的游戏中。我的方法是异步运行吗?

如何冻结功能被初始化:

// Declarations 
DrawableAd drawableAd; 

// Inside constructor of my game class 
AdComponent.Initialize("MyAppId"); 
Rectangle rect = new Rectangle(0, resolution_h_ - 50, 320, 50); 
drawableAd_ = AdComponent.Current.CreateAd("AdId", rect, false); // false is to set AutoRefresh of the ad 

为了使广告点击和下载它,我在每一个更新步骤打电话:AdComponent.Current.Update(e_.ElapsedTime);

DrawableAd infos

的问题是如果我同时调用它,则会使我的游戏在下载新广告时冻结一段时间:

private void OnUpdate(object sender, GameTimerEventArgs e) 
{ 
    // ... GameUpdates 
    AdComponent.Current.Update(e.ElapsedTime); 
} 

所以,我虽然解决的办法是把AdComponent.Current.Update(e.ElapsedTime);放在后台线程上,用“低优先级”来解决冻结问题。所以我做:

private async void UpdateAds() 
    { 
     if (ad_update_completed_) 
      await Task.Factory.StartNew(() => UpdateAdsMethod()); 
    } 

    private async Task UpdateAdsMethod() 
    { 
     ad_update_completed_ = false; 
     AdComponent.Current.Update(e_.ElapsedTime); 
     ad_update_completed_ = true; 
    } 

    private void OnUpdate(object sender, GameTimerEventArgs e) 
    { 
    // ... GameUpdates 
    e_ = e; 
    UpdateAds(); 
    } 

这一点,我发现后(不使用分析器),大部分的冻结(不是全部)的地方去了。但是我有一些疑问,因为编译器发出一个警告,说UpdateAdsMethod();将被同步执行。

我在做什么错?

+0

异步!=多线程。没有足够的信息来帮助优化你的代码。 – Aron

+0

@Aron我可以添加什么信息? –

+0

从分析器获得的结果当然。 –

回答

1

AdComponent.Current.Update()不返回任务所以你UpdateAdsMethod可以简化(见下文)。由于您在子任务内调用UpdateAdsMethod(),因此不需要让它返回另一个任务。它应该简单地读取如下:

private void UpdateAdsMethod() 
    { 
     ad_update_completed_ = false; 
     AdComponent.Current.Update(e_.ElapsedTime); 
     ad_update_completed_ = true; 
    } 

这应该消除编译器警告。请记住,如果在任何使用等待关键字的方法中,使用等待的方法的签名必须在方法声明中包含异步。请参阅下面的UpdateAds()

你的方法是在后台确实运行,因为呼叫是在孩子的任务(你在UpdateAds()

编辑创建它:所以,你的代码现在应该类似于:

private async Task UpdateAds() 
    { 
     if (ad_update_completed_) 
      await Task.Factory.StartNew(() => UpdateAdsMethod()); 
    } 

    private void UpdateAdsMethod() 
    { 
     ad_update_completed_ = false; 
     AdComponent.Current.Update(e_.ElapsedTime); 
     ad_update_completed_ = true; 
    } 

欲了解更多信息,请访问http://msdn.microsoft.com/en-us/magazine/jj991977.aspx

+0

你是否同意Daniel Mann的评论?我应该删除'StartNew'吗? –

+0

@misiMe不知道他在#2中的含义。这样做会导致很多_“考虑将”await“运算符应用于调用的结果”_编译器警告 – MickyD

+0

我无法相信我有多少不同意你的意见。 'UpdateAdsMethod()'看起来是线程不安全的。如果'公共无效UpdateAdsMethod'抛出你无法捕捉它,你的整个应用程序将停止运行。您应该返回一个任务,然后将其包装在Try Catch中。最后,名称“DrawableAdComponent”提示需要UI线程。 – Aron