【问题标题】:Asynchronously call a method which accepts a string and returns an int in C# [duplicate]在C#中异步调用一个接受字符串并返回一个int的方法[重复]
【发布时间】:2020-10-09 19:44:02
【问题描述】:

假设你有一个方法如下:

public int slowMethod(string ss)
    {
        Console.WriteLine("slow method exec starts");
        //Do some time taking work
        Thread.Sleep(3000);
        Console.WriteLine("slow method exec ends");
        return 1;
    }

你必须异步调用这个方法,但不能改变这个方法的签名,那你会怎么做呢?

【问题讨论】:

  • @MindSwipe 实际上在那个问题中 Foo 方法很简单,它不接受或返回任何值。我正面临这个挑战,因此决定使用接受并返回值的方法发布一个新答案。
  • 答案的核心概念是“不要这样做。从同步更改为异步将始终带来 API 更改”。此外,链接问题中的方法确实返回一个值,添加参数很简单
  • @MindSwipe 我只是在 C# 的控制台应用程序中玩弄异步代码,在一次采访中有人问我这个问题,所以我想在这里发布答案。
  • 如果您需要在另一个线程中运行同步方法,请使用Task.Run(() => SlowMethod("")),就这么简单。

标签: c# asynchronous async-await


【解决方案1】:

创建一个如下所示的包装类:

public async void slowMethodAsync()
{
    string ss = "my string value"; // or pass the value from caller of slowMethodAsync

    Task<int> T = Task.Run(() => {
        return slowMethod(ss);
    });

    var res = await Task.WhenAll(T);

    Console.WriteLine($"value of res[0]:{res[0]}");
}

并从Main方法调用slowMethodAsync,如下所示:

static void Main(string[] args)
{
    Console.WriteLine("main method begins");
    slowMethodAsync();                
    Console.WriteLine("main method end");
}

控制台输出:

main method begins

slow method exec starts

main method end

//after 3 seconds

slow method exec ends

value of res[0]:1

当有多个slowMethod需要异步运行时会更有利。

【讨论】:

  • 你也可以写var res = await Task.Run ...。另外,在题中,如果要Task.Delay(500)生效,必须等待。
  • @MichałTurczyn 是的,我们可以,但我使用了WhenAll(),以便我们可以调用多个 slowMethods
  • 另外,异步方法应该尽可能返回Task
  • @MichałTurczyn 将代码更改为使用 Thread.Sleep()。谢谢。
  • 请不要async void(除非您知道它仅用作顶级事件处理程序)。关于如何意外破坏整个应用程序的小示例:dotnetfiddle.net/yRsATj
猜你喜欢
  • 1970-01-01
  • 2020-11-02
  • 2021-05-02
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 2022-11-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多