2013-06-01 36 views
9

Tôi có một phương pháp mà tôi muốn chờ đợi nhưng tôi không muốn gây ra một hiệu ứng domino suy nghĩ bất cứ điều gì có thể gọi phương pháp gọi điện thoại này và chờ đợi nó. Ví dụ, tôi có phương pháp này:Làm cách nào tôi có thể chờ một phương thức không đồng bộ mà không có công cụ sửa đổi không đồng bộ trong phương thức gốc này?

public bool Save(string data) 
{ 
    int rowsAffected = await UpdateDataAsync(data); 
    return rowsAffected > 0; 
} 

Tôi gọi:

public Task<int> UpdateDataAsync() 
{ 
    return Task.Run(() => 
    { 
    return Data.Update(); //return an integer of rowsAffected 
    } 
} 

này sẽ không làm việc vì tôi có phải đặt "async" trong chữ ký phương pháp Save() và sau đó tôi có thể Không trả lại bool Tôi phải làm cho nó Task<bool> nhưng tôi không muốn bất cứ ai đang chờ phương thức Save().

Có cách nào tôi có thể tạm ngưng thực thi mã như chờ đợi hoặc bằng cách nào đó đang chờ mã này mà không có công cụ sửa đổi không đồng bộ không?

+2

Tôi sẽ rất khó chịu nếu bạn cho tôi truy cập vào phương thức 'Lưu' chặn chuỗi của tôi, do đó buộc tôi phải gọi điện trong 'Task', đó chính xác là những gì bạn có thể trả lại cho tôi ngay từ đầu . Chỉ cần nói. –

Trả lời

7

Làm cách nào để chờ phương thức async mà không có công cụ sửa đổi không đồng bộ trong phương thức gốc này?

Điều đó giống như hỏi "làm thế nào tôi có thể viết một ứng dụng bằng C# nhưng không phụ thuộc vào bất kỳ loại thời gian chạy .NET nào?"

Câu trả lời ngắn: không làm điều đó. Thực sự, những gì bạn đang làm ở đây là lấy một phương pháp tự nhiên đồng bộ (Update), làm cho nó xuất hiện không đồng bộ bằng cách chạy nó trên một thread thread thread (UpdateDataAsync), và sau đó bạn muốn chặn nó làm cho phương thức không đồng bộ xuất hiện đồng bộ (Save). Cờ đỏ nghiêm trọng.

Tôi khuyên bạn nên nghiên cứu cẩn thận cặp blog nổi tiếng của Stephen Toub should I expose asynchronous wrappers for my synchronous methodsshould I expose synchronous wrappers for my asynchronous methods. Câu trả lời cho cả hai câu hỏi là "không", mặc dù Stephen Toub giải thích một số tùy chọn để làm điều đó nếu bạn thực sự phải.

Điều đó "thực sự phải" nên được dành riêng cho cấp ứng dụng. Tôi giả định các phương pháp này (Update, UpdateDataAsyncSave) nằm trong các lớp khác nhau của ứng dụng (ví dụ: mô hình dữ liệu/dịch vụ dữ liệu/chế độ xem). Lớp dịch vụ dữ liệu/dữ liệu không được thực hiện chuyển đổi đồng bộ/không đồng bộ. Mức xem mô hình (ứng dụng cụ thể) là cấp duy nhất có lý do để thực hiện loại chuyển đổi đó - và nó chỉ nên làm như một phương sách cuối cùng.

+0

Điều gì sẽ xảy ra nếu tôi viết một trường hợp thử nghiệm nơi tôi đặt nội dung vào cơ sở dữ liệu (với trình điều khiển Async) và sau đó đọc ngay lập tức? Chỉ cần nói, có những trường hợp sử dụng hợp pháp để lập trình đồng bộ. – Hypershadsy

+0

@ Hypershadsy: Tại sao bạn không thể làm điều đó một cách không đồng bộ? –

+0

Bạn có thể viết các trường hợp kiểm tra không đồng bộ? – Hypershadsy

3

Chỉnh sửa: câu trả lời này trước khi Task.Run được thêm vào. Với bối cảnh bổ sung đó, kịch bản được mô tả tốt nhất là "không làm điều đó".


Bạn có thể truy cập hoặc sử dụng .Result.Wait(), nhưng bạn cần phải biết làm thế nào công việc được thực hiện đầu tiên. Đặc biệt, bạn cần phải biết liệu nó có sử dụng ngữ cảnh đồng bộ hay không. Lý do quan trọng là nếu nó thực hiện điều này có thể bế tắc ngay lập tức, vì một số bối cảnh đồng bộ cần bối cảnh gọi để thoát hoàn toàn (ví dụ, bối cảnh đồng bộ của MVC cần phải thoát khỏi phương thức hành động của bộ điều khiển).

Để bảo vệ điều này là khó, nhưng bạn có lẽ nên luôn xác định rõ ràng thời gian chờ có cuộc gọi đến .Wait() - chỉ trong trường hợp.

+0

Cảm ơn bạn, tôi đang sử dụng Task.Run - Tôi đã cập nhật câu hỏi của mình để hiển thị phương thức thứ hai – Neal

+0

@Neal với chỉnh sửa, tôi sẽ nói "không làm điều đó" - bạn đang thêm chuỗi không có lý do gì. Bạn cũng có thể làm việc đó trên chuỗi đang chờ đợi. –

+2

@Neal: Marc hoàn toàn đúng; về cơ bản những gì bạn đang làm ở đây là thuê một người nào đó chờ đợi thay cho bạn, và sau đó chờ đợi cho đến khi họ hoàn thành công việc của họ, đang chờ bạn thay mặt bạn. Bạn sẽ không thuê ai đó để làm điều đó trong cuộc sống thực, vì vậy đừng làm điều đó ở đây. Nếu bạn cần phải đợi đồng bộ cho công việc được thực hiện thì hãy làm như vậy; nếu bạn muốn tiếp tục làm việc trong khi chờ đợi thì 'chờ đợi' nó. –

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