Making interface implementations async

前端 未结 3 1117
太阳男子
太阳男子 2020-12-23 02:26

I’m currently trying to make my application using some Async methods. All my IO is done through explicit implementations of an interface and I am a bit confused about how to

相关标签:
3条回答
  • 2020-12-23 03:10

    Better solution is to introduce another interface for async operations. New interface must inherit from original interface.

    Example:

    interface IIO
    {
        void DoOperation();
    }
    
    interface IIOAsync : IIO
    {
        Task DoOperationAsync();
    }
    
    
    class ClsAsync : IIOAsync
    {
        public void DoOperation()
        {
            DoOperationAsync().GetAwaiter().GetResult();
        }
    
        public async Task DoOperationAsync()
        {
            //just an async code demo
            await Task.Delay(1000);
        }
    }
    
    
    class Program
    {
        static void Main(string[] args)
        {
            IIOAsync asAsync = new ClsAsync();
            IIO asSync = asAsync;
    
            Console.WriteLine(DateTime.Now.Second);
    
            asAsync.DoOperation();
            Console.WriteLine("After call to sync func using Async iface: {0}", 
                DateTime.Now.Second);
    
            asAsync.DoOperationAsync().GetAwaiter().GetResult();
            Console.WriteLine("After call to async func using Async iface: {0}", 
                DateTime.Now.Second);
    
            asSync.DoOperation();
            Console.WriteLine("After call to sync func using Sync iface: {0}", 
                DateTime.Now.Second);
    
            Console.ReadKey(true);
        }
    }
    

    P.S. Redesign your async operations so they return Task instead of void, unless you really must return void.

    0 讨论(0)
  • 2020-12-23 03:20

    Neither of these options is correct. You're trying to implement a synchronous interface asynchronously. Don't do that. The problem is that when DoOperation() returns, the operation won't be complete yet. Worse, if an exception happens during the operation (which is very common with IO operations), the user won't have a chance to deal with that exception.

    What you need to do is to modify the interface, so that it is asynchronous:

    interface IIO
    {
        Task DoOperationAsync(); // note: no async here
    }
    
    class IOImplementation : IIO
    {
        public async Task DoOperationAsync()
        {
            // perform the operation here
        }
    }
    

    This way, the user will see that the operation is async and they will be able to await it. This also pretty much forces the users of your code to switch to async, but that's unavoidable.

    Also, I assume using StartNew() in your implementation is just an example, you shouldn't need that to implement asynchronous IO. (And new Task() is even worse, that won't even work, because you don't Start() the Task.)

    0 讨论(0)
  • 2020-12-23 03:22

    An abstract class can be used instead of an interface (in C# 7.3).

    // Like interface
    abstract class IIO
    {
        public virtual async Task<string> DoOperation(string Name)
        {
            throw new NotImplementedException(); // throwing exception
            // return await Task.Run(() => { return ""; }); // or empty do
        }
    }
    
    // Implementation
    class IOImplementation : IIO
    {
        public override async Task<string> DoOperation(string Name)
        {
            return await await Task.Run(() =>
            {
                if(Name == "Spiderman")
                    return "ok";
                return "cancel";
            }); 
        }
    }
    
    0 讨论(0)
提交回复
热议问题