2013-08-21 66 views
5

Tôi có một số mã đang chạy sẽ đóng băng nếu bạn lấy và di chuyển cửa sổ trong khi đang tải. Tôi không chắc chắn vấn đề là gì nhưng tôi nghĩ rằng tôi sẽ đăng mã của tôi kể từ khi tôi khá mới làm việc với async/await và chỉ cần tự hỏi nếu có một số vấn đề với logic của tôi. Tôi không nói điều này gây ra vấn đề, tôi vừa tìm kiếm và thấy các vấn đề khác với giao diện người dùng bị đóng băng và không đồng bộ/chờ đợi thường xuyên xuất hiện. Bất kỳ trợ giúp sẽ được đánh giá cao.Giao diện người dùng đóng băng với async/await

private async void BuildChart() 
{ 
    DateTime date = DateTime.Today; 
    using (Database db = new Database()) 
    { 
     await BuildActual(date, db); 
     await BuildActual(date.AddDays(1),db); 
    } 
} 

private async Task BuildActual(DateTime date, Database db) 
{ 
    List<TimeSeries> actualValues = await Task<List<TimeSeries>>.Factory.StartNew(() => 
    { 
     try 
     { 
      var wind = DoStuff(date, db); 
      if (wind == null) return null; 
      if (wind.Count == 0) return null; 
      return MakeTimeSeries(wind); 
     } 
     catch 
     { 
      return null; 
     } 
    }); 

    try 
    { 
     if (actualValues == null) return; 
     DoMoreStuff(actualValues); 
    } 
    catch (Exception ex) 
    { 
     Logger.Log(ex); 
    } 
} 

Cảm ơn.

Trả lời

18

async không làm cho các vấn đề giao diện người dùng của bạn biến mất một cách kỳ diệu, nhưng nó chắc chắn sẽ giúp bạn quản lý chúng.

Trong trường hợp này, BuildActual phương pháp của bạn (mà should be namedBuildActualAsync) là lần đầu tiên không đồng bộ chờ đợi DoStuffMakeTimeSeries trên một sợi nền (mà should be using Task.Run instead of TaskFactory.StartNew).

Cho đến nay, rất tốt. Sau khi ủy nhiệm hoàn thành việc thực thi, BuildActual tiếp tục thực hiện trên luồng giao diện người dùng và chạy DoMoreStuff đồng bộ (trên chuỗi đó).

Do đó, sự cố của bạn có thể do DoMoreStuff chiếm quá nhiều thời gian. Nếu bạn vẫn không chắc chắn, hồ sơ ứng dụng (hoặc thậm chí Debug.WriteLine được kết hợp với Stopwatch) sẽ cung cấp cho bạn thông tin chi tiết hơn về nơi chuỗi giao diện người dùng đang bận.

P.S. Bạn cũng nên avoid async void, như tôi giải thích chi tiết hơn trong bài viết MSDN của tôi.

P.P.S. Vì bạn mới sử dụng async, tôi khuyên bạn nên my own intro article, có liên kết đến (IMO) tài nguyên theo dõi tốt nhất ở cuối.

+0

Cảm ơn các hướng dẫn/liên kết khởi động chuyên sâu. Tôi thực sự phát hiện ra vấn đề không liên quan đến mã nhưng các bài báo đã giúp đỡ bất kể. – Kohins