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 Result
Codeusing 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
IO
monad is theEnvIO
. If you pass your ownEnvIO
toRun
orRunAsync
then you are expected to dispose it. If you don't pass anEnvIO
toRun
orRunAsync
, then one will be generated for you and it will be disposed automatically.For
Eff
, the same is true for theEnvIO
. TheRT
runtime 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 theEnvIO
that you pass toRunAsync
Case4()
is correct and all resources will be cleaned-up automatically.Case5()
is only correct if yourRuntime
has no…