Tôi đang viết một ứng dụng giao diện điều khiển C# đơn giản sử dụng các nhiệm vụ không đồng bộ và khung thực thể (với ý định chạy nó dưới Linux (RHEL) với Mono, nhưng đó là một thử thách hoàn toàn khác). Lưu ý rằng tôi đang nhắm mục tiêu .NET 4.0, vì vậy tôi đang sử dụng .ContinueWith()
thay vì await
.Yêu cầu không rõ ràng về Generic ContinueWith
này, cộng với mô hình EF DB của một cơ sở dữ liệu Northwind, là toàn bộ các ứng dụng:
using System;
using System.Linq;
using System.Threading.Tasks;
namespace MonoEF
{
class Program
{
private static Model.NorthwindEntities _db = new Model.NorthwindEntities();
static void Main(string[] args)
{
try
{
GetCustomerNamesAsync().ContinueWith(t => {
if (t.IsFaulted) Console.WriteLine(t.Exception.Flatten.ToString);
else if (t.IsCompleted) foreach (string result in t.Result) Console.WriteLine(result);
});
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private static Task<string[]> GetCustomerNamesAsync()
{
return Task.Factory.StartNew(() => (from c in _db.Customers select c.ContactName).Distinct().ToArray());
}
}
}
Vấn đề là tôi nhận được lỗi sau tại .ContinueWith()
:
Ambiguous Invocation:
System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task<string[]>>) (in class Task<string[]>)
System.Threading.Tasks.Task.ContinueWith(System.Action<System.Threading.Tasks.Task>) (in class Task)
match
Với tôi, lời gọi không nên mơ hồ, trình biên dịch nên thích Task chung hơn Task không chung chung, đặc biệt là nó là đầu ra của GetCustomerNamesAsync()
. Tuy nhiên, với tư cách là một nhà phát triển VB.NET, tôi có thể dựa vào Option Infer
trong tình huống này.
Tôi làm cách nào để cho trình biên dịch biết được lời gọi mà tôi muốn sử dụng trong C#?
Bạn đã đưa tôi đến giải pháp đúng. Khai báo rõ ràng '.ContinueWith ((Task t) => {...})' sau đó đã vạch trần vấn đề tiếp theo, rằng tôi đã gọi 'Console.WriteLine (t.Exception.Flatten.ToString)' thay vì 'Console.WriteLine (t.Exception.Flatten(). ToString()) '. Sau khi sửa lỗi này, tôi đã có thể loại bỏ khai báo tham số lambda rõ ràng, và trình biên dịch đã được hạnh phúc. –
MCattle
@MCattle Thú vị rằng các dấu ngoặc đơn còn thiếu sẽ làm cho trình biên dịch không thể quyết định giữa hai quá tải. Tôi hơi nghi ngờ về câu trả lời của chính mình bởi vì tôi không bao giờ nhớ phải đưa ra kiểu đầu vào lambda một cách rõ ràng vô số lần tôi đã sử dụng 'ContinueWith'. Tôi không thể giải thích tại sao những dấu ngoặc đơn còn thiếu sẽ tạo nên sự khác biệt. –
Làm cho tinh thần với tôi, bởi vì quá tải được suy ra bằng cách sử dụng, và nếu có một lỗi cú pháp trong việc sử dụng, sau đó quá tải chính xác không thể suy ra. – MCattle