(私はlanguage-extプロジェクトの著者です) Task
自体がブロックしている場合以外は、式がハングアップする根本的な理由はありません。Map
とBind
は特に巧妙なことはしない単純な関数であり、間違いなく同期などはしないでください。私はただのlang-EXTでユニットテストにこのコードを追加し、それが正常に返されます:それは言及する価値がある
public class Account : NewType<Account, Unit>
{
public Account(Unit _) : base(unit) { }
}
Either<Exception, Account> GetAccountWithID(int accountId) =>
Account.New(unit);
Task<Either<Exception, bool>> Initialize(Account c) =>
Task.FromResult(Right<Exception, bool>(true));
[Fact]
public void StackOverflowQuestion()
{
int accountID = 0;
var res = GetAccountWithID(accountID)
.Map(c => Initialize(c))
.Bind(t => t.Result);
}
ことの一つは、それが仕事に.Result
を呼び出すには絶好の練習ではないということです。あなたは間違いなくあなたのためのよりよいこの作品を作るために、言語-EXT内の他の機能を利用することができます。たとえば
:
var task = from c in GetAccountWithID(accountID).AsTask()
from r in Initialize(c)
select r;
AsTask
が、それはLINQ式で使用可能だ意味Task<Either<Exception, Account>>
、にEither<Exception, Account>
を持ち上げますInitialize
(Task
も返されます)。あなたは基本的にLINQの構文に反対している場合
、その後、あなたが行うことができます:
var task = GetAccountWithID(accountID).AsTask().BindT(Initialize);
task
は、Task<Either<Exception, bool>>
であるあなたはawait
次のことができます。
var res = (await task).IfLeft(false);
別のトリック(あなたが」バージョン2.0.*
を使用して)Sequence
を使用して、内側と外側のモナドを反転させることです。
var res = task.Sequence();
これにより、Task<Either<Exception, bool>>
はEither<Exception, Task<bool>>
になります。これは一致します。明らかに、あなたのユースケースに応じて、最も適切なものが決まります。
ありがとう、@louthster。私はこれを調べます。私はLINQ構文(私は他の場所でそれを使用する)に反対ではない、私はちょうどバインド/マップのイディオムに慣れている。私は確認しますが、私は現在、Nugetで利用できる安定したバージョンであるため、1.xバージョンの最後のバージョンを使用していると思います。 – melston
私は、非同期/待機待ちインフラストラクチャの詳細をさらに高速化する予定です。私はAsTask()拡張を認識していませんでした。そして、私はこれがあなたの提案する方法で使用できることを理解していませんでした。 – melston