C# 对I/O绑定操作使用异步函数
我在看这份文件,上面说: 对于I/O绑定代码,您将等待一个操作返回一个任务或异步方法内部的任务。 我有两个问题: Q1-对于I/O绑定的代码,这是否意味着我们需要使用C# 对I/O绑定操作使用异步函数,c#,.net,asynchronous,C#,.net,Asynchronous,我在看这份文件,上面说: 对于I/O绑定代码,您将等待一个操作返回一个任务或异步方法内部的任务。 我有两个问题: Q1-对于I/O绑定的代码,这是否意味着我们需要使用Task.Factory.StartNew(…,TaskCreationOptions.longlunning)或TaskCompletionSource 问题2-我在下面编写了两个简单的控制台应用程序来模拟I/O绑定代码,我的方法正确吗 class Program //use Task.Factory.StartNew {
Task.Factory.StartNew(…,TaskCreationOptions.longlunning)
或TaskCompletionSource
问题2-我在下面编写了两个简单的控制台应用程序来模拟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程序//使用Task.Factory.StartNew
{
静态异步任务主(字符串[]args)
{
var task=ReadFile();
Console.WriteLine(“做其他工作”);
int total=等待任务;
Console.WriteLine($“读取{total}行”);
Console.ReadLine();
}
静态异步任务ReadFile()
{
返回wait Task.Factory.StartNew(new Func(Read)、TaskCreationOptions.LongRunning);
}
静态int Read()
{
Thread.Sleep(5000);//模拟读取操作
return 9999;//已读取9999行
}
}
及
class程序//使用TaskCompletionSource
{
静态void Main(字符串[]参数)
{
var awaiter=ReadFile().GetAwaiter();
Console.WriteLine(“做其他工作”);
waiter.OnCompleted(()=>Console.WriteLine($“Read{waiter.GetResult()}行”);
Console.ReadLine();
}
静态任务ReadFile()
{
var tcs=new TaskCompletionSource();
新线程(()=>
{
SetResult(Read());
}).Start();
返回tcs.Task;
}
静态int Read()
{
Thread.Sleep(5000);//模拟读取操作
return 9999;//已读取9999行
}
}
Q1-对于I/O绑定的代码,这是否意味着我们需要使用Task.Factory.StartNew(…,TaskCreationOptions.longlunning)
或TaskCompletionSource
没有
这意味着您使用async
和wait
问题2-我在下面编写了两个简单的控制台应用程序来模拟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
}
}
没有
I/O本质上是不同步的,因此使用Thread.Sleep
代替I/O工作是不正确的。I/O本质上是异步的,因此合适的占位符是wait 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
}
}
class程序//使用异步/等待
{
静态异步任务主(字符串[]args)
{
var task=ReadFileAsync();
Console.WriteLine(“做其他工作”);
var结果=等待任务;
WriteLine($“读取{result}行”);
Console.ReadLine();
}
静态异步任务ReadFileAsync()
{
等待任务。延迟(5000);//模拟读取操作
return 9999;//已读取9999行
}
}
在一般I/O情况下。这就是为什么使用
Thread.Sleep
会把一切都抛在脑后;当I/O不需要线程时,它强制使用线程。提示:I/O绑定函数应该具有async
方法。例如System.IO
,或Stream
的WriteAsync
,等等。一如既往,回答得非常好。值得注意的是,async main
在c#7之前不可用。没有它,答案就复杂了一点。(如果你还没有升级,你应该升级!)@Stephen Cleary非常感谢你的回答。另一个问题是:您不知道读取操作需要多长时间,可能超过5秒,那么Task.Delay(…)是如何实现的;在这里工作,你不知道延迟方法中应该放什么数字?@secondimage:任务。延迟是“在这里做异步工作”的占位符。它不应该出现在最终代码中;它将被实际的异步工作所取代(例如,异步读取文件)。