2011-06-30 38 views
6

Bản sao có thể xảy ra:
Must every BeginInvoke be followed by an EndInvoke?
Is EndInvoke() optional, sort-of optional, or definitely not optional?Gọi không đồng bộ - Yêu cầu EndInvoke phải không?

Tôi đã có một ứng dụng đa luồng, và một trong những chủ đề phụ nào cần phải nhận được một số mã để thực thi trên các chủ đề chính một lần vài phút. Không có bất kỳ giá trị trả lại nào và chuỗi thứ hai không quan tâm nếu nó làm tăng bất kỳ ngoại lệ nào hoặc không chạy được.

Cho đến giờ, tôi đã làm cho nó chạy mã qua Form.Invoke, nhưng đôi khi mất nhiều thời gian hơn bình thường (một vài giây) và chặn chuỗi cho đến khi hoàn thành. Tôi cần chuỗi thứ hai để có thể tiếp tục thực hiện mà không bị trì hoãn trong vài giây.

BeginInvoke có vẻ như sẽ thực hiện công việc một cách độc đáo, nhưng tôi không thực sự có bất kỳ nơi nào để gọi EndInvoke, vì tôi không muốn đợi hoặc nhận lại giá trị. Và xem xét rằng mã được gọi liên quan đến một loạt các cuộc gọi bản địa, tôi không chắc chắn nếu nó là một ý tưởng tốt để không EndInvoke.

Tôi có cần gọi số EndInvoke hay không, hoặc có cách nào khác để nhận mã chạy trên chuỗi biểu mẫu chính không đồng bộ mà tôi nên sử dụng thay thế không?

Cảm ơn =)

Trả lời

6

Bạn có thể gọi EndInvoke để truy xuất giá trị trả lại từ đại biểu, nếu cần thiết, nhưng điều này không bắt buộc. EndInvoke sẽ chặn cho đến khi giá trị trả về có thể được truy xuất.

Nguồn: http://msdn.microsoft.com/en-us/library/0b1bf3y3.aspx dưới chú thích

+0

Tuyệt vời, vì vậy tôi chỉ có thể thay đổi 'Gọi của tôi thành' BeginInvoke 'mà không cần thổi bất cứ thứ gì lên. –

3

Bạn nên đảm bảo rằng EndInvoke được gọi, nhưng bạn có thể làm điều đó khá dễ dàng, một cái gì đó như:

var action = new Action(SomeMethodGroup); 

    action.BeginInvoke(new AsyncCallback(

     x => (x.AsyncState as Action).EndInvoke(x)), action); 
+0

Tôi tin rằng OP đang nói về Form.BeginInvoke nói riêng và không phải là Begin/EndInvoke mô hình nói chung. Nhìn vào MSDN, Form.BeginInvoke dường như không theo mô hình Begin/EndInvoke chính xác. – dtb

+0

@ dtb, Trên thực tế, tôi không tin rằng nó là cần thiết cho Form.BeginInvoke hoặc Delegate.BeginInvoke, vì tôi tin rằng nó chỉ tạo ra một WaitHandle nếu bạn cố gắng chờ đợi (tức là gọi EndInvoke.) WaitHandle cần phải được làm sạch lên, nhưng nó sẽ là nếu bạn đã gọi EndInvoke. –

+0

Điểm tốt, có thể bạn không cần EndInvoke, có thể là một phương pháp đơn giản có thể hoạt động như một chiến lược “lửa và quên”? –

4

Một cách điển hình để gọi EndInvoke là bằng cách bao gồm một callback hoàn thành với BeginInvoke để bạn có thể gọi EndInvoke trong cuộc gọi lại. Điều này quan trọng hơn đối với các phương thức Begin/End làm điều gì đó cụ thể hơn Invoke, chẳng hạn như BeginRead/EndRead; trong các trường hợp sau, kết thúc có thể được yêu cầu để làm sạch và cũng sẽ thường (lại) ném bất kỳ ngoại lệ nào đã xảy ra trong quá trình.

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