2011-01-18 5 views
8

Tôi có ứng dụng trình xem cơ sở dữ liệu WPF: Đây là cửa sổ chính đơn giản có chứa điều khiển người dùng với lưới dữ liệu hiển thị dữ liệu được trích xuất từ ​​cơ sở dữ liệu SQLite.
Vấn đề là ứng dụng này mất 6 giây để bắt đầu cho đến khi có thể sử dụng được.Cải thiện thời gian khởi động ứng dụng WPF nhận thức

Tôi đã thử xây dựng điều khiển người dùng (và thực hiện tất cả tải dữ liệu) trong hàm dựng của cửa sổ chính:
Màn hình giật sẽ hiển thị 5s theo cách này, sau đó tiếp theo là 1s của cửa sổ chính trống cho đến khi ứng dụng sẵn sàng để được sử dụng.
Người dùng cho biết phải mất quá nhiều thời gian cho đến khi có điều gì đó (trực quan) xảy ra.

Sau đó, tôi đã chuyển chế độ điều khiển người dùng (và tải dữ liệu) vào trình xử lý sự kiện được tải của cửa sổ chính: Màn hình giật sẽ hiển thị 3 giây, sau đó là 3s của cửa sổ chính trống cho đến khi ứng dụng sẵn sàng.
Người dùng nói rằng nó "tốt hơn", nhưng không thích thực tế là một nửa cửa sổ chính đã hoàn thành được hiển thị ở trạng thái bị tắt quá lâu.

Có một số lời khuyên chung về thời gian tải ứng dụng hoặc có bất kỳ đề xuất nào khác về tình trạng này có thể được cải thiện không?
Tôi tin rằng lý tưởng cửa sổ chính sẽ được hiển thị nhanh nhất có thể, cùng với kính hoặc kính xoay một giờ cho đến khi dữ liệu được tải. Nhưng sau đó tôi không thể chỉ di chuyển việc tạo điều khiển người dùng thành một nhân viên nền vì điều này sẽ được thực hiện trên một chuỗi sai.

Có ai có bất kỳ đề xuất nào về vấn đề này không?

Chỉnh sửa:
Lưu ý rằng ngay bây giờ tôi vừa gán truy vấn LINQ-to-EF làm nguồn dữ liệu lưới.
Một cải tiến khả năng có thể để tải dữ liệu này vào một bảng dữ liệu ở chế độ nền và gán nó chỉ một lần nạp ...

Edit2: Tôi đang sử dụng .net 4 với System.Data.SQLite và EF4 để tải dữ liệu. Có ít nhất 4000 hàng và 30 cột.

+0

Bạn đang tải bao nhiêu dữ liệu từ cơ sở dữ liệu? Bạn đang tải dữ liệu như thế nào - sử dụng ORM (nếu có, cái nào?) Hoặc ADO.NET đơn giản? – alimbada

+0

Giáo dục người dùng rằng rất nhiều điều đang diễn ra. Kiểm tra những gì đang thực sự diễn ra và tối ưu hóa cho phù hợp. Một màn hình đăng nhập, hoặc giật gân mở rộng (với một số hình động lượn sóng/progressbar) có thể chính xác những gì họ đang tìm kiếm. – CodingBarfield

+0

@alimbada: Tôi đã chỉnh sửa câu hỏi để bao gồm thông tin này. Nhưng nó là một câu hỏi chung hơn là gắn với Entity Framework, vv ADO.NET hoặc bất kỳ ORM sẽ mất thời gian để tải dữ liệu, bạn cũng có thể thay thế điều này bằng Thread.Sleep (..). Câu hỏi đặt ra là làm thế nào để đối phó với tình huống này. – Marc

Trả lời

13

Tải dữ liệu của bạn không đồng bộ. Trình bày một cái gì đó tốt đẹp trên GUI cho người dùng trong khi tải. Các mã sau đây có thể giúp bạn với điều này:

BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true}; 
bgWorker.DoWork += (s, e) => {  
    // Load here your file/s  
    // Use bgWorker.ReportProgress(); to report the current progress 
}; 
bgWorker.ProgressChanged+=(s,e)=>{  
    // Here you will be informed about progress and here it is save to change/show progress. 
    // You can access from here savely a ProgressBars or another control. 
}; 
bgWorker.RunWorkerCompleted += (s, e) => {  
// Here you will be informed if the job is done. 
// Use this event to unlock your gui 
}; 
bgWorker.RunWorkerAsync(); 

Ứng dụng không phải là nhanh hơn nhưng nó có vẻ là nhanh hơn nhiều vì giao diện là ngay lập tức nhìn thấy được và đáp ứng. Có lẽ bạn cũng có thể hiển thị cho người dùng một phần của dữ liệu được tải trong khi tải phần còn lại. Sử dụng số ProgressChanged -để thực hiện việc này.

Cập nhật

Tôi không chắc chắn nếu tôi hiểu vấn đề của bạn đúng. Nếu vấn đề của bạn không phải là dữ liệu thời gian cần được tải, thì có điều gì đó lạ trong ứng dụng của bạn. WPF là IMO rất nhanh. Việc tạo điều khiển không mất nhiều thời gian. Tôi hình dung nhiều danh sách lớn hơn khi bạn đề cập trong một vài phần nghìn giây.

Hãy thử tìm xem bạn có điều gì đó trong giao diện người dùng của bạn cản trở DataGrid để ảo hóa các mục. Có lẽ bạn có một proplem ở đó. Để phân tích các ứng dụng WPF, tôi có thể giới thiệu cho bạn WPF Profiling Tools.

+0

Ngoài ra, đây là cách Silverlight làm điều đó. (Cú pháp khác nhau, cùng một nguyên tắc.) –

+0

Vâng, đó là cách tôi xử lý các hoạt động chậm cho đến bây giờ và nó hoạt động khá tốt. Vấn đề duy nhất là trước khi gọi bgWorker.RunWorkerAsync() bạn phải vô hiệu hóa giao diện người dùng nếu không nó có thể gây nhầm lẫn cho người dùng. – Marc

+1

@Marc: Có, tuy nhiên có thể bạn chỉ có thể vô hiệu hóa một số phần của giao diện người dùng, đó là một trải nghiệm thú vị cho người dùng. Như tôi đã viết, nếu dữ liệu nằm độc đáo, bạn cũng có thể trình bày một vài bản ghi hoặc tệp đầu tiên được tải và cho phép người dùng đã làm việc với chúng. Nhưng rõ ràng, tất cả những điều tốt đẹp này đều tốn thời gian phát triển và làm cho mọi thứ trở nên phức tạp hơn.Câu hỏi đặt ra là, nếu khách hàng sẽ trả tiền cho nó và nếu nó có ý nghĩa để phức tạp dự án incerement ... – HCL

2

Điều rõ ràng nhất bạn có thể làm là lập hồ sơ cho ứng dụng của bạn và tìm các nút cổ chai trong thời gian khởi động. Có vẻ như thủ phạm có khả năng nhất sẽ là tải dữ liệu từ cơ sở dữ liệu của bạn.Một bài học tôi đã học được là nếu bạn đang sử dụng ORM, khi tải các tập dữ liệu lớn nếu bạn ủng hộ POCO (Plain Old CLR/C# Objects) trên các thực thể cơ sở dữ liệu được tạo ORM (xem ví dụ bên dưới), tải thời gian sẽ nhanh hơn rất nhiều và sử dụng RAM sẽ giảm đáng kể. Lý do cho điều này là EF sẽ cố gắng tải toàn bộ thực thể (nghĩa là tất cả các trường của nó) và có thể tải toàn bộ dữ liệu liên quan đến các thực thể của bạn, hầu hết trong số đó bạn thậm chí sẽ không cần. Thời gian duy nhất bạn thực sự cần phải làm việc trực tiếp với các thực thể là khi bạn đang thực hiện các hoạt động chèn/cập nhật/xóa. Khi đọc dữ liệu, bạn chỉ nên chỉ nhận các trường mà ứng dụng của bạn cần hiển thị và/hoặc xác thực.

Nếu bạn theo mẫu MVVM, kiến ​​trúc trên không khó thực hiện.

Ví dụ về dữ liệu tải vào POCOs với EF:

var query = from entity in context.Entities 
       select new EntityPoco 
       { 
        ID = entity.ID, 
        Name = entity.Name 
       }; 

return query.ToList(); 

POCOs các lớp học rất đơn giản với autoproperties cho từng lĩnh vực.

Chúng tôi thường có kho lưu trữ cho từng thực thể trong các ứng dụng của chúng tôi và mỗi kho lưu trữ có trách nhiệm nhận/cập nhật dữ liệu liên quan đến thực thể đó. Các mô hình khung nhìn có tham chiếu tới các kho lưu trữ mà chúng cần để chúng không sử dụng EF trực tiếp. Khi người dùng thực hiện các thay đổi cần được duy trì, chúng tôi sử dụng các phương thức khác trong kho lưu trữ, sau đó chỉ tải một tập hợp con của các thực thể (ví dụ: những người dùng đã thay đổi) và áp dụng các cập nhật cần thiết - với một số xác thực được thực hiện bởi viewmodel và xác thực khác đang diễn ra trong DB thông qua các ràng buộc/trình kích hoạt, v.v.

+0

+1 cho đề xuất của bạn. Tôi đã làm hồ sơ ứng dụng. Nó thực sự là nhiều hơn hoặc ít hơn 3s ứng dụng (và khung) khởi tạo mà tôi sẽ không thể cải thiện. 3s khác đến từ việc tạo điều khiển người dùng và tải dữ liệu. Tôi cũng nghĩ về việc sử dụng các trình đọc dữ liệu ADO.NET cơ bản để cải thiện hiệu năng. – Marc

+0

Bạn có liên kết nào tốt với các ví dụ MVVM đang hiển thị cách họ xử lý tải dữ liệu trong nền không? Họ đang làm gì với chế độ xem trong khi tải? – Marc

+0

Xin lỗi, tôi không có bất kỳ ví dụ trực tuyến nào trong tầm tay; đó là những thứ tôi học được từ một đồng nghiệp. Tôi đã thêm ví dụ của riêng mình và được xây dựng một chút về câu trả lời ban đầu của tôi. Cá nhân tôi có thể xác minh rằng nó hoạt động, bởi vì ứng dụng chúng tôi hiện đang làm việc trên ban đầu mất hơn một phút rưỡi để tải. Bây giờ nó xuống dưới 10 giây. Chúng tôi đang thực hiện từ 300k đến 400k lần đọc từ SQL Server DB lúc khởi động ... – alimbada

0

Có nhiều lý do cho việc này.

1) Máy triển khai có thể có cấu hình khá thấp.
2) Đúng hoặc vấn đề với ràng buộc dữ liệu.

giải pháp có thể sẽ là:
1) Lazy tải dữ liệu
2) Tối ưu hóa hiệu suất. http://msdn.microsoft.com/en-us/library/aa970683.aspx

Tôi đã thấy các ứng dụng hiển thị bản ghi 5 triệu ít hơn một giây trong wpf.

PS: Một trong những lý do ít nhất có thể có thể là 30 cột, do truy cập thứ tự cột.