2013-04-06 38 views
0

我正在開發一個Win 8應用程序,它需要基於用戶輸入的數據進行一些可能的長時間運行循環和計算。這種計算經常運行以實時更新結果。爲WinRT/Windows 8開發一流的異步開發

計算由計算器類完成。我將使用示例代碼來出主意

public class ResultCalculator 
{ 
    List<Data> Input1 = new List<Data>(); 
    IQueryable<int> Input2; 
    IQueryable<Data2> Input3; 

    public ResultCalculator(List<int> items1, List<Data2> items2) 
    { 
     items1.Sort((x,y) => y.CompareTo(x)); 
     Input2 = items1.AsQueryable(); 
     Input3 = items2.AsQueryable().OrderByDescending(w => w.LValue); 
    } 

    public void CalculateLValues() 
    { 
     foreach (var v in Input3) 
     { 
      for (int i = 1; i <= v.Quantity; i++) 
      { 
       if (Input1.Count > 0) 
       { 
        Data existing = FindExisting(v.LValue, 4); 

        if (existing != null) 
        { 
         existing.Add(v.LValue); 
        } 
        else 
        { 
         FindNew(v.LValue); 
        } 
       } 
       else 
       { 
        FindNew(v.LValue); 
       } 
      } 
     } 

     OptimisePass1(); 
    } 

    public void FindNew(int LValue) 
    { 
     int options = FindNewItem(LValue, 0); 

     if (options != 0) 
     { 
      Data newdata = new Data(options); 
      newdata.Add(LValue); 
      Input1.Add(newdata); 
     } 
    } 

    public void OptimisePass1() 
    { 
     foreach (var w in Input1) 
     { 
      var ShorterLValues = from sl in Input2 where sl < w.LValue orderby sl select sl; 

      foreach (var sl in ShorterLValues) 
      { 
       if (sl > w.LValue - w.Remaining) 
       { 
        w.LValue = sl; 
        w.CalculateRemaining(); 
       } 
      } 

    // MORE CALCULATION TO DO IN ANOTHER LOOP 
     } 
    } 

    public Data FindExisting(int LValueRequired, int additionalvalue) 
    { 
     Input1.OrderBy(w => w.LValue); 

     foreach (var sl in Input1.Where(i => i.Remaining > 0).OrderBy(i => i.Remaining)) 
     { 
      if (sl.Remaining >= LValueRequired + additionalvalue) 
      { 
       return sl; 
      } 
     } 
     return null; 
    } 

    public int FindNewItem(int LValueRequired) 
    { 
     foreach (var sl in Input2) 
     { 
      if (sl >= LValueRequired + 4) 
      { 
       return sl; 
      } 
     } 
     return 0; 
    } 

} 

這個類是從下面我的ViewModel使用...

public async Task UpdateCalculationAsync() 
{ 
    var data1 = new List<int>(sInput); 
    var reqlist = new List<Data2>(sInput2); 

    var lc = new ResultCalculator(data1, data2); 
    NL.Clear(); 

    await Task.Run(() => lc.CalculateLValues()); 

    foreach (var i in lc.Data1) 
    { 
     NL.Add(i); 
    } 
} 

沒有任何的異步使用此舉起了UI,當它跑了,如果有列表中有很多項目。所以我添加了「等待Task.Run(()=> lc.CalculateLValues())」使它運行異步。我已經掌握了異步的基本知識,但並沒有真正理解如何正確地讓我的類在async中運行。這種方法是否正確?

我相信我已經完成了後臺線程的計算。當然UI現在保持響應並且可以在計算運行時使用。一旦計算出結果,我的viewmodel就會得到結果並更新UI。我真正想要的是我的ResultCalculator類具有可以等待的任務返回方法。然而,我真的爲如何重構而苦苦掙扎。我甚至不確定如果這是有效的,並且是有效的方法,那麼就有必要。但我並不是100%相信這是正確使用異步模式,而是想檢查它是否可以改進?

回答

0

建議做這樣的事情:

// user will do some action on the UI to trigger the compute 
public async Task Button1_Click(..) 
{ 
    await this.ViewModel.RecalculateAsync(); 
} 

class ViewModel 
{ 
    public async Task RecalculateAsync() 
    { 
     var data1 = new List<int>(sInput); 
     var reqlist = new List<Data2>(sInput2); 
     var lc = new ResultCalculator(data1, data2); 
     await Task.Run(() => lc.CalculateLValues()); 
     // I am not sure that is NL - if it is items like property on viewmodel that is bound to ListView like control in xaml - that should be fine. 
     // otherwise, add code here to add the list of result items to an observable collection 
     // expose this collection as Items property on viewmodel and bind in xaml to ListView.ItemsSource 
    } 
}