2009-11-08 25 views
5

Tôi đang viết một giao diện người dùng dữ liệu đơn giản bằng cách sử dụng tiêu chuẩn .Net databinding đến một DataSet đã nhập từ SQL Server.Chạy một hộp thoại phương thức trên một chủ đề không phải là giao diện người dùng

Tôi có nút tải lại gọi Fill trên tất cả DataAdapters để nhận dữ liệu mới từ cơ sở dữ liệu (trong trường hợp người dùng khác thay đổi dữ liệu).

Quá trình này mất một khoảng thời gian, trong đó giao diện người dùng bị đóng băng. Nó phải được chạy trên thread UI hoặc các trình xử lý sự kiện databinding ném ngoại lệ cross-thread.

Tôi muốn hiển thị hộp thoại "Vui lòng đợi" trên một chuỗi nền (để có thể hoạt ảnh) trong khi chuỗi giao diện người dùng kết nối với cơ sở dữ liệu.

Làm cách nào để hiển thị hộp thoại phương thức trên chuỗi không phải là giao diện người dùng?


EDIT: Tôi biết rằng thực hành tốt nhất là để chạy các hoạt động ở chế độ nền, nhưng tôi không thể làm điều đó bởi vì trong những sự kiện liên kết dữ liệu.

Trả lời

8

Bạn nên làm điều ngược lại. Chạy quy trình chạy dài của bạn trên chuỗi nền và để nguyên chuỗi giao diện người dùng miễn phí để phản hồi hành động của người dùng.

Nếu bạn muốn chặn bất kỳ hành động nào của người dùng trong khi xử lý, bạn có một số tùy chọn, bao gồm các hộp thoại phương thức. Một khi các sợi nền hoàn chế biến, bạn có thể thông báo cho các chủ đề chính về kết quả

+0

Như tôi đã giải thích trong câu hỏi, tôi không thể. Tôi biết rõ rằng đây là phương pháp hay nhất. – SLaks

+0

Tôi nghĩ bạn vẫn có thể. Nó chỉ có nghĩa là luồng nền không nên cập nhật trực tiếp dữ liệu. Truy xuất chúng, đóng gói chúng và ủy quyền cho chủ đề chính để cập nhật giao diện người dùng – mfeingold

+0

Tôi hiểu tình trạng khó xử của bạn, nhưng tôi vẫn nghĩ những gì tôi đề xuất là tốt hơn (ít rắc rối) hơn thay thế – mfeingold

0
using(var frmDialog = new MyPleasWaitDialog()) { 
    // data loading is started after the form is shown 
    frmDialog.Load += (_sender, _e) { 
     // load data in separate thread 
     ThreadPool.QueueWorkItem((_state)=> { 
      myAdapter.Fill(myDataSet); 
      // refresh UI components in correct (UI) thread 
      frmDialog.Invoke((Action)myDataControl.Refresh); 
      // close dialog 
      frmDialog.Invoke((Action)frmDialog.Close()); 
     } 
    } 

    // shows dialog 
    frmDialog.ShowDialog(this); 
} 
+0

Bạn cần tải dữ liệu trong DataSet khác nhau, mà không bị ràng buộc để datagrid, và sau đó rebind datagrid vào tập dữ liệu mới. Và/hoặc thử sử dụng "BeginLoadData()" và "EndLoadData" trên tập dữ liệu/datatable. – TcKs

+1

Như tôi đã cố gắng giải thích trong câu hỏi, 'myAdapter.Fill' ném một InvalidOperationException trong trình xử lý sự kiện databinding của lưới khi được gọi trên một luồng nền. Gọi 'BeginLoadData' trên bàn không giúp ích gì. – SLaks

+1

Vì vậy, bạn cần điền vào một tập dữ liệu khác và sau đó rebind datagrid để dụ "mới" (đầy) tập dữ liệu. – TcKs

2

Mã chạy trong databinding sự kiện cần phải được tách riêng từ giao diện người dùng, có lẽ sử dụng một số loại đối tượng chuyển giao dữ liệu.

Sau đó, bạn có thể chạy thao tác truy vấn trong một chuỗi riêng biệt hoặc BackgroundWorker và để nguyên chuỗi giao diện người dùng.

Edit: Các thực sự cách nhanh chóng để khắc phục điều này là để có được những sự kiện để chạy trong đại biểu của mình bằng InvokeRequired.Invoke. Điều đó sẽ cung cấp cho bối cảnh giao diện người dùng phương thức. Đồng nghiệp của tôi thực hiện điều này giống như nó biến mất theo phong cách và nó làm tôi khó chịu vì không hiếm khi có ý tưởng tốt để làm theo cách này ... nhưng nếu bạn muốn một giải pháp nhanh thì điều này sẽ hiệu quả. (Tôi không làm việc nên tôi không có mẫu với tôi; tôi sẽ cố gắng tìm ra thứ gì đó.)

Chỉnh sửa 2: Tôi không chắc bạn đang yêu cầu điều gì. Tôi đã tạo một ứng dụng mẫu tạo ra một hộp thoại phương thức trong một chủ đề khác, và nó kết thúc là vô dụng. Thay vì sử dụng hộp thoại phương thức, bạn có thể sử dụng một số điều khiển hoặc tập hợp các điều khiển khác để chỉ ra sự thay đổi tiến trình, rất có thể trực tiếp trên cùng một biểu mẫu?

+0

Có cách nào đơn giản để làm điều này và vẫn sử dụng databinding tiêu chuẩn với các sự kiện cập nhật? Tôi đang cố gắng hoàn thành dự án này một cách nhanh chóng. – SLaks

+0

Re. Chỉnh sửa: Tôi không thể đặt các cuộc gọi 'Invoke' bên trong DataGrid. – SLaks

+0

Re: Chỉnh sửa 2: Bạn có thể rất đúng. Nếu đó là một câu hỏi đơn giản, tôi sẽ không hỏi nó ở đây. Đối với việc đặt điều khiển trên biểu mẫu, điều đó thậm chí còn tệ hơn - đó là _completely_ không thể có một số điều khiển trên một biểu mẫu thuộc sở hữu của một chuỗi khác. – SLaks

0

Dưới đây là một ví dụ của việc sử dụng BackgroundWorker để làm việc tải dữ liệu và chạy một hình thức thân thiện với người sử dụng để hiển thị 'Đang tải hồ sơ' hoặc tương tự ...

public void Run() 
    { 
     bgWorkrFillDS = new BackgroundWorker(); 
     bgWorkrFillDS.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorkrFillDS_RunWorkerCompleted); 
     bgWorkrFillDS.DoWork += new DoWorkEventHandler(bgWorkrFillDS_DoWork); 
     bgWorkrFillDS.RunWorkerAsync(); 
    } 

    void bgWorkrFillDS_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BackgroundWorker bgWrkrFillDS = (BackgroundWorker)sender as BackgroundWorker; 
     if (bgWrkrFillDS != null) 
     { 
      // Load up the form that shows a 'Loading....' 
      // Here we fill in the DS 
      // someDataSetAdapter.Fill(myDataSet); 
     } 
    } 


    void bgWorkrFillDS_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     // Hide or unload the form when the work is done 
    } 

Hope this helps ... Chăm sóc , Tom.

+1

Vui lòng đọc câu hỏi. Việc gọi 'someDataSetAdapter.Fill' trên luồng nền sẽ ném một InvalidOperationException. – SLaks

0

Tôi đã giải quyết vấn đề này bằng cách tạo một Số liệu mới, tải trong nền, sau đó gọi DataSet.Merge trên chuỗi giao diện người dùng. Cảm ơn tất cả mọi người cho lời khuyên của bạn, dẫn đến giải pháp này.

Là phần thưởng bổ sung, điều này chạy nhanh hơn nhiều hơn so với trước đây (gọi Fill ở chế độ nền, chỉ hoạt động mà không có lưới mở). Có ai biết tại sao không?

Các vấn đề liên quan