等待IO的可重用测试代码 [英] Reusable test code that waits for IO

查看:92
本文介绍了等待IO的可重用测试代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在WCF公开的方法/服务上使用async/await.一切正常,但我想模拟实际等待IO的服务方法,以便将服务调用注册到IO完成端口,并将线程放回线程池中.

I'm experimenting with using async/await on WCF exposed methods/services. Everything works fine but I'd like to simulate the service method actually waiting for IO so that the service call will be registered with an IO completion port, and the thread put back into the thread pool.

为澄清起见,我只是在尝试确认IO完成端口的使用,并更好地了解实际情况.

To clarify, I'm just experimenting to confirm usage of IO completion ports and to get a better understanding of the mechanics of what's actually going on.

例如我的测试服务当前如下所示:

So e.g. my test service currently looks like this:

[ServiceContract]
public interface IHelloWorldService
{
    [OperationContract]
    Task<string> SayHello(string firstName, string lastName);
}


public class HelloWorldService : IHelloWorldService
{
    public async Task<string> SayHello(string firstName, string lastName)
    {
        string str = string.Format("Hello {0} {1}", firstName, lastName);
        return await Task.Factory.StartNew(() => str);
    }
}

我想在SayHello()中执行一些操作,以使该代码等待某些IO,理想情况下,当我要模拟等待IO时,通常可以复制/粘贴该代码模式以供一般使用.

I'd like to do something in SayHello() to cause that code to wait for some IO, ideally a code pattern I can copy/paste to use generally when I want to simulate waiting for IO.

典型地,Thread.Sleep()用于模拟长时间运行的任务,但是我敢肯定,它将使线程池线程进入睡眠状态,并且不会触发IO完成端口的使用.

Typically Thread.Sleep() is used to simulate a long running task, but I'm pretty sure that will put the thread pool thread to sleep and not trigger usage of an IO completion port .

推荐答案

当我要模拟等待IO时可以复制/粘贴以通常使用的代码模式.

a code pattern I can copy/paste to use generally when I want to simulate waiting for IO.

通常Thread.Sleep()用于模拟长时间运行的任务

Typically Thread.Sleep() is used to simulate a long running task

如注释中所述,await Task.Delay(..)Thread.Sleep(..)的异步等效项.通常用于表示未指定的异步操作".

As already mentioned in the comments, await Task.Delay(..) is the asynchronous equivalent of Thread.Sleep(..). It's commonly used to represent an "unspecified asynchronous operation".

public async Task<string> SayHello(string firstName, string lastName)
{
    await Task.Delay(TimeSpan.FromSeconds(2));
    return string.Format("Hello {0} {1}", firstName, lastName);
}

但是,如果这是一个测试/模拟存根,那么您可能不想想要延迟一段真实的时间.异步测试存根通常与Task.FromResult(或Task.FromExceptionTask.FromCancelled)同步实现:

However, if this is a test/mock stub, then you probably don't want to delay for a real amount of time. Asynchronous test stubs are generally implemented synchronously with Task.FromResult (or Task.FromException or Task.FromCancelled):

public Task<string> SayHello(string firstName, string lastName)
{
    return Task.FromResult(string.Format("Hello {0} {1}", firstName, lastName));
}

但是听起来您想强制异步.请注意,在单元测试中很少需要执行此操作,但是它确实会不时出现.要强制异步而不占用宝贵的时间,请使用Task.Yield:

But it sounds like you want to force asynchrony. Note that needing to do this in a unit test is rare, but it does come up from time to time. To force asynchrony without taking up valuable time, use Task.Yield:

public async Task<string> SayHello(string firstName, string lastName)
{
    await Task.Yield();
    return string.Format("Hello {0} {1}", firstName, lastName);
}

这篇关于等待IO的可重用测试代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆