Đây là mã:IAsyncResult.AsyncWaitHandle.WaitOne() hoàn thành trước callback
class LongOp
{
//The delegate
Action longOpDelegate = LongOp.DoLongOp;
//The result
string longOpResult = null;
//The Main Method
public string CallLongOp()
{
//Call the asynchronous operation
IAsyncResult result = longOpDelegate.BeginInvoke(Callback, null);
//Wait for it to complete
result.AsyncWaitHandle.WaitOne();
//return result saved in Callback
return longOpResult;
}
//The long operation
static void DoLongOp()
{
Thread.Sleep(5000);
}
//The Callback
void Callback(IAsyncResult result)
{
longOpResult = "Completed";
this.longOpDelegate.EndInvoke(result);
}
}
Đây là trường hợp thử nghiệm:
[TestMethod]
public void TestBeginInvoke()
{
var longOp = new LongOp();
var result = longOp.CallLongOp();
//This can fail
Assert.IsNotNull(result);
}
Nếu đây là chạy test có thể thất bại. Tại sao chính xác?
Có rất ít tài liệu về cách delegate.BeginInvoke hoạt động. Có ai có bất kỳ thông tin chi tiết nào mà họ muốn chia sẻ không?
Cập nhật Đây là trường hợp điều kiện tinh tế không được ghi chép rõ trong MSDN hoặc ở nơi khác. Vấn đề, như được giải thích trong câu trả lời được chấp nhận, đó là khi hoạt động hoàn thành Wait Handle được báo hiệu, và sau đó Callback được thực thi. Các tín hiệu phát hành các chủ đề chính chờ đợi và bây giờ thực hiện gọi lại vào "cuộc đua". Jeffry Richter's suggested implementation cho biết điều gì đang xảy ra phía sau hậu trường:
// If the event exists, set it
if (m_AsyncWaitHandle != null) m_AsyncWaitHandle.Set();
// If a callback method was set, call it
if (m_AsyncCallback != null) m_AsyncCallback(this);
Để biết giải pháp, hãy tham khảo câu trả lời của Ben Voigt. Việc triển khai đó không phải chịu thêm chi phí của một lần chờ xử lý thứ hai.
Xóa cuộc gọi lại và thử lại. – jgauffin
@jgauffin, nếu bạn nhận thấy câu hỏi không hỏi "Làm cách nào để làm việc này?" Rõ ràng đây là một ví dụ giả tạo. –
Câu hỏi của bạn là: "Nếu điều này xảy ra, trường hợp thử nghiệm có thể không thành công. Tại sao lại chính xác?". Tôi * đã * trả lời điều đó. Bởi vì bạn cố gắng kết hợp hai cách khác nhau để xử lý một hoạt động không đồng bộ. – jgauffin