Warm tip: This article is reproduced from serverfault.com, please click

c#-Task.Run()的这种用法不好吗?

(c# - Is this usage of Task.Run() bad practice?)

发布于 2020-11-28 00:13:41

如果使用Task.Run在这种情况下,是否合理呢?
当前,我在WinForms应用程序中运行此代码,但稍后将在ASP.NET项目中将其用作HostedService/ BackgroundService我不确定这是否具有可比性。

在阅读了有关async / await的多个博客之后,Tasks我觉得Task.Run(() => ..应该在calling方法中实现Manager.SyncLoop()但是,如果的实现IConnection是真正异步的,那不是代码的味道吗?

private async void button1_Click(object sender, EventArgs e)
    {
        // this should be handled by the BackgroudService, WinForms is used just for testing
        var m = new Manager();
        m.Connection = new ConnectionA();
        m.ExecuteAsync();
    }
}
public interface IConnection
{
    Task<object> ReadAsync();
}

// assume that i cannot change this 
public class SomeLib
{
    private Random random = new Random();
    public object SyncReading()
    {
        Thread.Sleep(5000);
        return random.Next(); ;
    }
}

public class ConnectionA : IConnection
{
    private SomeLib lib = new SomeLib();
    public Task<object> ReadAsync()
    {
        // is this usage of Task.Run ok?
        var v = Task.Run(() => lib.SyncReading());
        return v;
    }

    // this will block UI
    //public Task<object> ReadAsync()
    //{
    //    return Task.FromResult(lib.SyncReading());
    //}
}

public class Manager 
{
    public IConnection Connection { get; set; }
    public async Task ExecuteAsync()
    {          
        await SyncLoop();
    }

    public async Task SyncLoop()
    {
        while (true)
        {
            var i = await Connection.ReadAsync();

            await Task.Delay(2000);
        }
    }
}
Questioner
rosi97
Viewed
11
Stephen Cleary 2020-11-28 08:21:36

首先,你可以改变IConnection吗?此同步实现是主要实现,还是仅仅是众多实现之一?

如果可以更改IConnection,则使其同步,并可以使用Task.RunExecuteAsync

如果IConnection需要保持异步,那么我会说要实现ConnectionA.ReadAsync同步。然后像往常一样Task.Run放入ExecuteAsync该技术背后的关键是异步(-Task返回)签名意味着实现可以是异步的,而不是必须是异步的。