我正在阅读这份文档https://docs.microsoft.com/en-us/dotnet/csharp/async,其中说:
对于绑定到I / O的代码,您需要等待一个操作,该操作将在异步方法内部返回Task或Task。
我有两个问题:
针对I / O绑定代码的Q1-,是否表示我们需要使用Task.Factory.StartNew(..., TaskCreationOptions.LongRunning)
或TaskCompletionSource
Q2-我在下面编写了两个简单的控制台应用程序来模拟受I / O约束的代码,我的方法正确吗?
class Program //use Task.Factory.StartNew
{
static async Task Main(string[] args)
{
var task = ReadFile();
Console.WriteLine("Do other work");
int total = await task;
Console.WriteLine($"Read {total} lines");
Console.ReadLine();
}
static async Task<int> ReadFile()
{
return await Task.Factory.StartNew(new Func<int>(Read), TaskCreationOptions.LongRunning);
}
static int Read()
{
Thread.Sleep(5000); // simulate read operation
return 9999; // 9999 lines has been read
}
}
和
class Program // use TaskCompletionSource
{
static void Main(string[] args)
{
var awaiter = ReadFile().GetAwaiter();
Console.WriteLine("Do other work");
awaiter.OnCompleted(() => Console.WriteLine($"Read {awaiter.GetResult()} lines"));
Console.ReadLine();
}
static Task<int> ReadFile()
{
var tcs = new TaskCompletionSource<int>();
new Thread(() =>
{
tcs.SetResult(Read());
}).Start();
return tcs.Task;
}
static int Read()
{
Thread.Sleep(5000); // simulate read operation
return 9999; // 9999 lines has been read
}
}
答案 0 :(得分:3)
针对I / O绑定代码的Q1-,是否表示我们需要使用
Task.Factory.StartNew(..., TaskCreationOptions.LongRunning)
或TaskCompletionSource
否。
这意味着您使用async
和await
。
Q2-我在下面编写了两个简单的控制台应用程序来模拟受I / O约束的代码,我的方法正确吗?
否。
I / O本质上不是同步的,因此使用Thread.Sleep
是I / O工作的不正确替代。 I / O本质上是异步的,因此正确的占位符是await Task.Delay
。
class Program // use async/await
{
static async Task Main(string[] args)
{
var task = ReadFileAsync();
Console.WriteLine("Do other work");
var result = await task;
Console.WriteLine($"Read {result} lines");
Console.ReadLine();
}
static async Task<int> ReadFileAsync()
{
await Task.Delay(5000); // simulate read operation
return 9999; // 9999 lines has been read
}
}
在一般I / O情况下,为there is no thread。这就是为什么使用Thread.Sleep
会丢掉所有内容的原因;当I / O不需要一个线程时,它将强制使用一个线程。