我如何测试以确保此代码确实正在运行异步?

时间:2015-11-09 18:33:54

标签: c# asynchronous asp.net-web-api2

我已经调整了以下代码,尝试从Wasson的asp.net代码加载web api。

static public async Task<IEnumerable<T>> ExecuteAsync(HttpClient client, String endPoint)
    {
        IEnumerable<T> result = null;
        HttpResponseMessage response =  client.GetAsync(endPoint).Result;
        response.EnsureSuccessStatusCode();
        if (response.IsSuccessStatusCode)
        {
            var tResult = await response.Content.ReadAsStringAsync();
            result = JsonConvert.DeserializeObject<IEnumerable<T>>(tResult);
        }
        return result;
    }

正如我设计的那样,我认为这个程序将以异步方式运行,但我不确定如何测试它以确保它。

我是使用异步编码的新手,所以任何建议都会有所帮助。

调用程序如下:

public virtual IEnumerable<T> Fill()
    {
        IEnumerable<T> result = null;
        try
        {
            using (var client = CreateClient("", new MediaTypeWithQualityHeaderValue("application/json")))
            {

                String _endPoint = "api/" + typeof(T).Name + "/Get";

                result = (ExecuteAsync(client, _endPoint)).Result;
            }
        }
        catch (Exception ex)
        {
            LogError(ex.Message);

        }
        return result;
    }

这个组合是否可能像我想要的那样异步运行?

我希望能够异步运行它的原因是Fill例程从数据库中获取大量数据。虽然某些记录的大小也可能是一个问题,但更多的是每个记录都有大量单个记录而不是大尺寸记录。

我不想要的是坐在那里的用户在与数据库进行通信时正在等待整个页面加载。

在这种情况下,无论我是直接连接到数据库还是通过我正在使用的网络API,都无关紧要:在某些情况下,无论哪种方式都需要很长时间。

我也担心死锁:一个大的抓取进入而另一个挂起。

我最初在Mike Wasson的示例代码之后构建了代码,但发现代码无限期地挂起,即使它已编译。

这有助于改善情况吗?

1 个答案:

答案 0 :(得分:0)

不确定你在这里交配后是什么。 您发布的代码仍将阻止它所在的线程,因为您正在调用将阻止的结果。

result = (ExecuteAsync(client, _endPoint)).Result;

您可以通过让async和await关键字扩展回最初创建请求的方法来使其异步。

public virtual async Task<IEnumerable<T>> Fill()
{
    ...
    result = await ExecuteAsync(client, _endPoint);
    ...
}

但是,自从你提到

之后,我不确定这是你所追求的
  

我不想要的是坐在那里的用户在与数据库进行通信时正在等待整个页面加载。

默认情况下,异步制作并不能解决这个问题。无论是同步还是异步,完成15秒的操作都需要15秒才能完成。不同之处在于,如果它是异步的,那么你的资源效率会更高(意思是,你可以在等待某些事情完成时释放线程以执行其他任务)。

但是,您可以使用任务来实现并行性。举个例子:

public void DoWork()
{
    Thread.Sleep(10000);
}

public void DoMoreWork()
{
    Thread.Sleep(10000);
}

如果我们这样称呼这两个

DoWork();
DoMoreWork();

然后需要20000毫秒或20秒 如果我们使它异步

public async Task DoWork()
{
    await Task.Delay(10000);
}

public async Task DoMoreWork()
{
    await Task.Delay(10000);
}

并像这样称呼它

await DoWork();
await DoMoreWork();

然后它还需要20秒才能完成。但是,由于DoWork和DoMoreWork可以独立于每个人运行,我们可以同时运行它们

await Task.WhenAll(DoWork(), DoMoreWork());

这将(在一个完美的世界中)导致两个任务在10秒内完成,将用户必须等待的时间减半。

希望我对这个问题有所了解:)