简体   繁体   English

Task.Run() 的这种用法是不好的做法吗?

[英]Is this usage of Task.Run() bad practice?

If the use of Task.Run in this case justifiable?如果在这种情况下使用Task.Run有道理吗?
Currently I run this code in a WinForms app, but later on it will be used in a ASP.NET project as a HostedService / BackgroundService .目前我在 WinForms 应用程序中运行此代码,但稍后它将在 ASP.NET 项目中用作HostedService / BackgroundService I am not sure if this is comparable then.我不确定这是否具有可比性。

After reading multiple blogs about async/await and Tasks I feel like the Task.Run(() =>.. should be implemented in the calling method Manager.SyncLoop() . But what if the implementation of IConnection is truely asynchronous, wouldn't that be code smell?在阅读了有关 async/await 和Tasks的多个博客之后,我觉得Task.Run(() =>..应该在调用方法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);
        }
    }
}

First, can you change IConnection ?首先,你能改变IConnection吗? Is this synchronous implementation the primary one, or is it just one of many?这个同步实现是主要的,还是只是其中之一?

If you can change IConnection , then make it synchronous, and you can use Task.Run in the implementation of ExecuteAsync .如果您可以更改IConnection ,则使其同步,您可以ExecuteAsync的实现中使用Task.Run

If IConnection needs to remain asynchronous, then I would say to implement ConnectionA.ReadAsync synchronously.如果IConnection需要保持异步,那么我会说同步实现ConnectionA.ReadAsync Then have the Task.Run in ExecuteAsync as normal.然后像往常一样在ExecuteAsyncTask.Run The key behind this technique is that an asynchronous ( Task -returning) signature means that the implementation may be asynchronous, not that it must be asynchronous.这种技术背后的关键是异步(返回Task )签名意味着实现可能是异步的,而不是它必须是异步的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM