I would like to inquire about the proper usage of Disposable and DisposableAsync
#1366
-
|
Excuse, me I am currently studying version 5 and would like to utilize Thank you for your assistance. Best regards, Version5.0.0-beta-18 ResultCodeusing LanguageExt;
using LanguageExt.Sys.Live;
using static LanguageExt.Prelude;
Console.WriteLine("## 1. Expect");
await Expect();
Console.WriteLine("\n## 2. use using IO");
await Case2();
Console.WriteLine("\n## 3. use using IO w/ EnvIO");
await Case3();
Console.WriteLine("\n## 4. use using Eff");
await Case4();
Console.WriteLine("\n## 5. use using Eff w/ Runtime");
await Case5();
async Task Expect()
{
try
{
await using var x = new DisposableClass("1");
throw new Exception("crash");
}
catch { }
}
async Task Case2()
{
var io =
from _1 in use(() => new DisposableClass("2"))
from __ in liftIO(() => throw new Exception("crash"))
from _2 in release(_1)
select unit;
try
{
await io.RunAsync();
}
catch { }
}
async Task Case3()
{
var io =
from _1 in use(() => new DisposableClass("3"))
from __ in liftIO(() => throw new Exception("crash"))
from _2 in release(_1)
select unit;
try
{
await io.RunAsync(EnvIO.New());
}
catch { }
}
async Task Case4()
{
Eff<Unit> effect =
from _1 in use(() => new DisposableClass("4"))
from __ in liftIO(() => throw new Exception("crash"))
from _2 in release(_1)
select unit;
await effect.RunAsync();
}
async Task Case5()
{
Eff<Runtime, Unit> effect =
from _1 in use(() => new DisposableClass("5"))
from __ in liftIO(() => throw new Exception("crash"))
from _2 in release(_1)
select unit;
await effect.RunAsync(Runtime.New());
}
public class DisposableClass(string Id) : IDisposable, IAsyncDisposable
{
public void Dispose()
{
Console.WriteLine($"- Disposed {Id}");
}
public ValueTask DisposeAsync()
{
Console.WriteLine($"- DisposedAsync {Id}");
return ValueTask.CompletedTask;
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
|
The only disposable 'thing' in the For So, for your functions:
It should also be noted that certain IO functions create local 'scopes' that do partial disposals. For example, This also happens in
In terms of NOTE: The resource-management system has had minimal testing so far. If there's one area of NOTE 2.0: I saw an issue in one of the EDITI should really read questions properly before answering! ;-) Anyway, all of the above is correct, but I realise you were specifically asking about support for public static IO<A> use<A>(Func<A> acquire, Func<A, IO<Unit>> release);
public static K<M, A> use<M, A>(K<M, A> acquire, Func<A, IO<Unit>> release);This version of However, having explicit support for I have also added implicit support for I added your examples to my TestBed app (with the correct-usage changes I mentioned at the start of this response). When I run it, I get: |
Beta Was this translation helpful? Give feedback.
The only disposable 'thing' in the
IOmonad is theEnvIO. If you pass your ownEnvIOtoRunorRunAsyncthen you are expected to dispose it. If you don't pass anEnvIOtoRunorRunAsync, then one will be generated for you and it will be disposed automatically.For
Eff, the same is true for theEnvIO. TheRTruntime is entirely your responsibility, because you pass it toRun, it's up to you to dispose it.So, for your functions:
Case2()is correct and all resources will be cleaned-up automatically.Case3()is wrong, you need to clean-up theEnvIOthat you pass toRunAsyncCase4()is correct and all resources will be cleaned-up automatically.Case5()is only correct if yourRuntimehas no…