использовать асинхронные функции для операций ввода-вывода - PullRequest
0 голосов
/ 02 июля 2019

Я читал этот документ https://docs.microsoft.com/en-us/dotnet/csharp/async, в котором говорится:

Для кода, связанного с вводом / выводом, вы ожидаете операцию, которая возвращает задачу или задачу внутри асинхронного метода.

У меня два вопроса:

Q1- для кода ввода-вывода, означает ли это, что нам нужно использовать Task.Factory.StartNew(..., TaskCreationOptions.LongRunning) или TaskCompletionSource

Q2 - Я написал два простых консольных приложения ниже для имитации кода, связанного с вводом / выводом, мой подход правильный?

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
    }
}

1 Ответ

3 голосов
/ 02 июля 2019

Q1- для кода ввода-вывода означает ли это, что нам нужно использовать Task.Factory.StartNew(..., TaskCreationOptions.LongRunning) или TaskCompletionSource

Нет.

Это означает, что выиспользуйте async и await.

В2. Я написал два простых консольных приложения ниже для имитации кода, связанного с вводом / выводом, мой подход правильный?

Нет.

Ввод / вывод по своей природе не является синхронным, поэтому использование Thread.Sleep является неправильной заменой работы ввода / вывода.Ввод / вывод по своей природе асинхронный, поэтому правильный заполнитель - 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
  }
}

В общем случае ввода / вывода нет потока .Вот почему использование Thread.Sleep отбрасывает все;вынуждает использовать поток, когда ввод / вывод не нужен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...