How to deal with IAsyncDisposable and IDisposable interfaces when no synchronous dispose available?

410 Views Asked by At

I am writing a Connection like class around an interop object. In particular, the closing of my connection is asynchronous.

The object I am interfacing with has a very poor API, like:

public interface InteropObject
{
    void StartLongTask();
    void IsLongTaskInProgress();
    void AbortLongTask();
}

All methods return immediately.

Here is the interface I ended up with:

public interface IConnection
{
    // [..]
    Task OpenAsync();
    Task RunOperationAsync();
    Task CloseAsync();
    // [..]
}

And the following implementation:

public class Connection : IConnection
{
    private InteropObject _myObject;

    Task OpenAsync()
    { // some required stuff }
    
    async Task RunOperationAsync()
    {
        _myObject.StartLongTask()
        while(_myObject.IsLongTaskInProgress())
        {
            await Task.Delay(TimeSpan.FromSeconds(1));
        }
    }

    async ask CloseAsync()
    {
        if(_myObject.IsLongTaskInProgress())
        {
            _myObject.AbortLongTask();
            // because the abort is not immediate, I have to wait until the end
            while(_myObject.IsLongTaskInProgress())
            {
                await Task.Delay(TimeSpan.FromSeconds(1));
            }
        }
    }
}

The problem I am facing is that I am a little bit confused about the approach to take, regarding the implementation or not of IDisposable along with IDisposableAsync. According to the MSDN:

It is typical when implementing the IAsyncDisposable interface that classes will also implement the IDisposable interface.

But in the MSDN exemple, the Utf8JsonWriter implements both a IDisposable and IDisposableAsync methods, which make the implementation of these interfaces easy in their example.

In my case, I do not have a synchronous cleanup operation. I don't want to implement such operation since I don't want the Close operation to return until the current operation is actually finished.

So, is okay to only implement IDisposableAsync ?

Or should I implement a synchronous Close method (that only calls _myObject.AbortLongTask();, or may be using an ugly Thread.Sleep() instead of Task.Delay()) and implement both IDisposable and IDisposableAsync?

0

There are 0 best solutions below