Hãy xem xét các đoạn mã sau:Cách tạo phương thức async trong C# 4 theo các phương pháp hay nhất?
public static Task<string> FetchAsync()
{
string url = "http://www.example.com", message = "Hello World!";
var request = (HttpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Http.Post;
return Task.Factory.FromAsync<Stream>(request.BeginGetRequestStream, request.EndGetRequestStream, null)
.ContinueWith(t =>
{
var stream = t.Result;
var data = Encoding.ASCII.GetBytes(message);
Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, data, 0, data.Length, null, TaskCreationOptions.AttachedToParent)
.ContinueWith(t2 => { stream.Close(); });
})
.ContinueWith<string>(t =>
{
var t1 =
Task.Factory.FromAsync<WebResponse>(request.BeginGetResponse, request.EndGetResponse, null)
.ContinueWith<string>(t2 =>
{
var response = (HttpWebResponse)t2.Result;
var stream = response.GetResponseStream();
var buffer = new byte[response.ContentLength > 0 ? response.ContentLength : 0x100000];
var t3 = Task<int>.Factory.FromAsync(stream.BeginRead, stream.EndRead, buffer, 0, buffer.Length, null, TaskCreationOptions.AttachedToParent)
.ContinueWith<string>(t4 =>
{
stream.Close();
response.Close();
if (t4.Result < buffer.Length)
{
Array.Resize(ref buffer, t4.Result);
}
return Encoding.ASCII.GetString(buffer);
});
t3.Wait();
return t3.Result;
});
t1.Wait();
return t1.Result;
});
}
Nó sẽ trả về Task<string>
, gửi yêu cầu HTTP POST với một số dữ liệu, trả lại kết quả từ máy chủ web trong một hình thức của chuỗi và được càng nhiều hiệu quả càng tốt.
- Bạn có phát hiện bất kỳ vấn đề nào liên quan đến luồng không đồng bộ trong ví dụ trên không?
- Bạn có thể có .Wait() bên trong .ContinueWith() trong ví dụ này
- Bạn có thấy bất kỳ vấn đề nào khác với sự an toàn của mã này không (trừ xử lý ngoại lệ sang một bên)?
Bạn nên chấp nhận một số câu trả lời từ các câu hỏi khác – Jimmy
Bạn có thể muốn xem xét đổi tên đối tượng Tác vụ của mình vì đã có đối tượng Tác vụ trong .NET 4. Trong khi bạn có thể làm cho chúng hoạt động cùng nhau, có thể dễ dàng thay đổi danh pháp. –
Mystere Man, tôi không có bất kỳ khai báo Task tùy chỉnh nào. Loại tác vụ tôi đang sử dụng là từ .NET 4.0 BCL. –