加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 创建异步包装器的方法

发布时间:2020-12-15 18:30:10 所属栏目:百科 来源:网络整理
导读:如何为同步方法创建异步包装器更好? // sync methodpublic void LongOperation(){ //code...}// versions of wrapperpublic async Task LongOpertionWrapperAsyncV1(){ var task = Task.Factory.StartNew(LongOperation); await task.ConfigureAwait(false)
如何为同步方法创建异步包装器更好?
// sync method
public void LongOperation()
{
    //code...
}


// versions of wrapper
public async Task LongOpertionWrapperAsyncV1()
{
    var task = Task.Factory.StartNew(LongOperation);
    await task.ConfigureAwait(false);
}

public Task LongOpertionWrapperAsyncV2()
{
    var task = Task.Factory.StartNew(LongOperation);
    task.ConfigureAwait(false);
    return task;
}

虽然两个版本的使用没有区别.

async Task Executor()
{
    await LongOpertionWrapperAsyncV1();
    await LongOpertionWrapperAsyncV2();
}

对于返回值的方法(Task< T>),我使用第一个版本.

但我想知道你的意见.

这些版本之间存在一般差异吗?

解决方法

你应该使用“像V2这样的东西:
public Task LongOpertionWrapperAsyncV2()
{
    return Task.Run(LongOperation);
}

async Task Executor()
{
    await LongOpertionWrapperAsyncV2().ConfigureAwait(false);
}

与V1相比,这可以节省一个上下文切换.只要你不需要“等待另一个操作”并且async-Task是方法中的最后一个操作,你就可以返回任务而不是等待它,并将await留给调用者(也可以或不能添加) ConfigureAwait).

只有在你想提供像HPT建议的TaskCreationOptions.LongRunning时,才需要Task.Factory.StartNew.

更新:
正如史蒂芬已经提到的那样:在很少的情况下你应该做同步异步(但有).因此,在实现这样的事情之前,请考虑一下你正在做什么.简化说:如果是CPU限制工作,请不要这样做,如果它是某种“等待IO”可能会这样做.
我们在这里有一个案例,我们开发了一个“几乎完全异步”的库,它可以控制不同的硬件设备.整个“通用库”是异步的,但是一些低级设备驱动程序和/或访问库不支持异步,因此在最低级别我们执行以下操作:

public Task<byte[]> ReadAsync(int length)
{
    return Task.Run(() => hwDevice.Read(length));
}

hwDevice.Read仍然会锁定线程,但不会锁定CPU,因此UI在此期间响应我们正在等待IO(在“实时”中也是一些取消和错误处理逻辑).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读