IcedTasks 0.11.7
dotnet add package IcedTasks --version 0.11.7
NuGet\Install-Package IcedTasks -Version 0.11.7
<PackageReference Include="IcedTasks" Version="0.11.7" />
paket add IcedTasks --version 0.11.7
#r "nuget: IcedTasks, 0.11.7"
// Install IcedTasks as a Cake Addin #addin nuget:?package=IcedTasks&version=0.11.7 // Install IcedTasks as a Cake Tool #tool nuget:?package=IcedTasks&version=0.11.7
IcedTasks
IcedTasks 是什么?
此库包含针对 计算表达式 的扩展 任务 CE,利用了 可恢复代码,这是在 F# 6.0 中引入的。
ValueTask<'T>
- 这利用了 .NET 的 ValueTask (这是一个 判别联合 of'Value | Task<'Value>
),可能在同步场景中有更好的性能。类似于 F#的任务表达式valueTask
valueTaskUnit
poolingValueTask
ColdTask<'T>
- 是unit -> Task<'T>
的别名。允许对任务进行懒加载评估(也称为冷加载),类似于 F# 的Async是冷的。coldTask
CancellableTask<'T>
- 是CancellationToken -> Task<'T>
的别名。允许对任务进行懒加载评估(也称为冷加载),类似于 F# 的 Async 是冷的。此外,允许将 CancellationToken 传递到计算中,类似于 F# 的 Async 取消支持。cancellableTask
cancellableBackgroundTask
CancellableValueTask<'T>
- 是CancellationToken -> ValueTask<'T>
的别名。允许对任务进行懒加载评估(也称为冷加载),类似于 F# 的 Async 是冷的。此外,允许将 CancellationToken 传递到计算中,类似于 F# 的 Async 取消支持。cancellableValueTask
cancellablePoolingValueTask
ParallelAsync<'T>
- 利用 应用性语法 允许并行执行 Async<'T> 表达式。有关为什么这是单独的计算表达式的说明,请参阅 此讨论。parallelAsync
AsyncEx<'T>
- 如下所述 F# 异步语义的变体,附带示例。asyncEx
- 这也可以通过
IcedTasks.Polyfill.Async
访问,该别名将 阴影 F# Async CE。async
Task<'T>
- F# Task CE 的修复的填充。可以通过IcedTasks.Polyfill.Task
访问,该别名将 阴影 F# Task CE。task
backgroundTask
Task
- 无返回值的Task
的 CE。taskUnit
backgroundTaskUnit
快速浏览差异
计算表达式1 | 库2 | TFM3 | 热/冷4 | 多次等待 5 | 多启动6 | 尾调用7 | CancellationToken 传播8 | 取消检查9 | 使用 and! 进行并行时10 | 使用 IAsyncDisposable11 |
---|---|---|---|---|---|---|---|---|---|---|
F# Async | FSharp.Core | netstandard2.0 | 冷 | 多次 | multiple | tailcalls | methodical | methodical | No | No |
F# AsyncEx | IcedTasks | netstandard2.0 | 冷 | 多次 | multiple | tailcalls | methodical | methodical | No | Yes |
F# ParallelAsync | IcedTasks | netstandard2.0 | 冷 | 多次 | multiple | tailcalls | methodical | methodical | Yes | No |
F# Task/C# Task | FSharp.Core | netstandard2.0 | Hot | 多次 | once-start | no tailcalls | explicit | explicit | No | Yes |
F# ValueTask | IcedTasks | netstandard2.0 | Hot | Once | once-start | no tailcalls | explicit | explicit | Yes | Yes |
F# ColdTask | IcedTasks | netstandard2.0 | 冷 | 多次 | multiple | no tailcalls | explicit | explicit | Yes | Yes |
F# CancellableTask | IcedTasks | netstandard2.0 | 冷 | 多次 | multiple | no tailcalls | methodical | methodical | Yes | Yes |
F# CancellableValueTask | IcedTasks | netstandard2.0 | 冷 | Once | multiple | no tailcalls | methodical | methodical | Yes | Yes |
- 1 - 计算表达式
- 2 - 它来自哪个 Nuget 包
- 3 - 这些在哪个 目标框架标识符 中可用
- <sup>4</sup> - 热异步代码块指已经启动并将最终产生值的代码块。冷异步代码块指尚未启动,必须由调用代码显式启动。请参阅 F# 异步教程 和 异步 C# 和 F#(第二部分):它们有什么不同? 以获取更多信息。
- <sup>5</sup> - ValueTask 等待模式
- <sup>6</sup> - 多启动指能够再次启动异步代码块。请参阅 任务启动常见问题解答 以获取更多信息。
- <sup>7</sup> - 允许在计算表达式中使用
let rec
。请参阅 尾递归 以获取更多信息。 - <sup>8</sup> -
CancellationToken
会传递到所有支持隐式CancellationToken
传递的类型。在async { ... }
(或其任何组合)内部的cancellableTask { ... }
调用将使用代码启动时的CancellationToken
。 - <sup>9</sup> - 在绑定和执行之前会检查取消。
- <sup>10</sup> - 允许利用计算表达式中的 应用符号 并行执行异步代码。
- <sup>11</sup> - 允许在计算表达式中使用
IAsyncDisposable
。请参阅 IAsyncDisposable 以获取更多信息。
为什么应该使用它?
AsyncEx
AsyncEx 与 Async相似,但在以下方式有所不同:
允许对 IAsyncDisposable 使用
use
关键字open IcedTasks let fakeDisposable () = { new IAsyncDisposable with member __.DisposeAsync() = ValueTask.CompletedTask } let myAsyncEx = asyncEx { use _ = fakeDisposable () return 42 }
允许对 Tasks/ValueTasks/任何可等待项 使用
let!/do!
open IcedTasks let myAsyncEx = asyncEx { let! _ = task { return 42 } // Task<T> let! _ = valueTask { return 42 } // ValueTask<T> let! _ = Task.Yield() // YieldAwaitable return 42 }
当 Tasks 抛出异常时,将使用在 Async.Await 覆载 中描述的行为(尤其是没有抛出 AggregateException 的 AwaitTask)
let data = "lol" let inner = asyncEx { do! task { do! Task.Yield() raise (ArgumentException "foo") return data } :> Task } let outer = asyncEx { try do! inner return () with | :? ArgumentException -> // Should be this exception and not AggregationException return () | ex -> return raise (Exception("Should not throw this type of exception", ex)) }
使用 IAsyncEnumerable 和
for
关键字。此示例使用 TaskSeq,但可以使用任何IAsyncEnumerable<T>
。open IcedTasks open FSharp.Control let myAsyncEx = asyncEx { let items = taskSeq { // IAsyncEnumerable<T> yield 42 do! Task.Delay(100) yield 1701 } let mutable sum = 0 for i in items do sum <- sum + i return sum }
对于 ValueTasks
- F# 目前还没有
valueTask
计算表达式。 直到此 PR 被合并。
open IcedTasks
let myValueTask = task {
let! theAnswer = valueTask { return 42 }
return theAnswer
}
对于冷和可取消的任务
- 您想要控制何时开始任务
- 您想要能够重新执行这些可执行任务
- 您不想在方法/函数中引入额外的
CancellationToken
参数 - 您希望在每次绑定之前处理取消检查的计算
ColdTask
简例
open IcedTasks
let coldTask_dont_start_immediately = task {
let mutable someValue = null
let fooColdTask = coldTask { someValue <- 42 }
do! Async.Sleep(100)
// ColdTasks will not execute until they are called, similar to how Async works
Expect.equal someValue null ""
// Calling fooColdTask will start to execute it
do! fooColdTask ()
Expect.equal someValue 42 ""
}
CancellableTask 和 CancellableValueTask
示例显示了 cancellableTask
,但可以将 cancellableValueTask
交换掉。
访问上下文的 CancellationToken
绑定到
CancellationToken -> Task<_>
let writeJunkToFile = let path = Path.GetTempFileName() cancellableTask { let junk = Array.zeroCreate bufferSize use file = File.Create(path) for i = 1 to manyIterations do // You can do! directly against a function with the signature of `CancellationToken -> Task<_>` to access the context's `CancellationToken`. This is slightly more performant. do! fun ct -> file.WriteAsync(junk, 0, junk.Length, ct) }
绑定到
CancellableTask.getCancellationToken
let writeJunkToFile = let path = Path.GetTempFileName() cancellableTask { let junk = Array.zeroCreate bufferSize use file = File.Create(path) // You can bind against `CancellableTask.getCancellationToken` to get the current context's `CancellationToken`. let! ct = CancellableTask.getCancellationToken () for i = 1 to manyIterations do do! file.WriteAsync(junk, 0, junk.Length, ct) }
简例
let executeWriting = task {
// CancellableTask is an alias for `CancellationToken -> Task<_>` so we'll need to pass in a `CancellationToken`.
// For this example we'll use a `CancellationTokenSource` but if you were using something like ASP.NET, passing in `httpContext.RequestAborted` would be appropriate.
use cts = new CancellationTokenSource()
// call writeJunkToFile from our previous example
do! writeJunkToFile cts.Token
}
ParallelAsync
- 当您想要并行执行多个异步操作并等待所有这些操作完成时。
简例
open IcedTasks
let exampleHttpCall url = async {
// Pretend we're executing an HttpClient call
return 42
}
let getDataFromAFewSites = parallelAsync {
let! result1 = exampleHttpCall "howManyPlantsDoIOwn"
and! result2 = exampleHttpCall "whatsTheTemperature"
and! result3 = exampleHttpCall "whereIsMyPhone"
// Do something meaningful with results
return ()
}
构建
GitHub Actions |
---|
NuGet
包名 | 稳定版 | 预览版 |
---|---|---|
IcedTasks |
开发中
请确保您的系统已安装以下 要求
- dotnet SDK 6.0 & 8.0
或
环境变量
CONFIGURATION
将设置 dotnet 命令的 配置。如果未设置,它将默认为 Release(发布版)。CONFIGURATION=Debug ./build.sh
将导致向命令添加-c
参数,如在dotnet build -c Debug
中所示。
GITHUB_TOKEN
将用于上传发布说明和 Nuget 包到 GitHub。- 在发布之前请务必设置此(配置)。
构建
> build.cmd <optional buildtarget> // on windows
$ ./build.sh <optional buildtarget>// on unix
你的库的 bin 目录应看起来类似于以下内容:
$ tree src/MyCoolNewLib/bin/
src/MyCoolNewLib/bin/
└── Debug
└── net50
├── MyCoolNewLib.deps.json
├── MyCoolNewLib.dll
├── MyCoolNewLib.pdb
└── MyCoolNewLib.xml
构建目标
Clean
- 清理源文件和临时目录。DotnetRestore
- 在 解决方案文件 上运行 dotnet restore。DotnetBuild
- 在 解决方案文件 上运行 dotnet build。DotnetTest
- 在 解决方案文件 上运行 dotnet test。GenerateCoverageReport
- 在DotnetTest
期间进行代码覆盖率,并通过 ReportGenerator 生成报告。WatchTests
- 使用测试项目运行 dotnet watch。这对于快速反馈循环非常有用。GenerateAssemblyInfo
- 为库生成 AssemblyInfo。DotnetPack
- 运行 dotnet pack。这包括运行 Source Link。SourceLinkTest
- 运行 Source Link 测试工具以验证是否正确生成了源链接。PublishToNuGet
- 通过 paket push 将DotnetPack
中生成的 NuGet 包发布到 NuGet。GitRelease
- 使用 发布说明 和通过发布说明
中的版本创建 commit 消息和 git 标签。GitHubRelease
- 发布带有发布说明和任何 NuGet 包的 GitHub 发布。FormatCode
- 在解决方案文件上运行 Fantomas。BuildDocs
- 从docsSrc
和库中的 XML 文档注释 生成文档。WatchDocs
- 生成文档并在本地启动一个 web 服务器。如果它检测到对docsSrc
文件、src
中的库或docsTool
本身的任何更改,它将重建和热重载。ReleaseDocs
- 将在BuildDocs
目标中生成的文档进行阶段化、commit 和推送。Release
- 运行所有发布类型任务的任务,例如PublishToNuGet
、GitRelease
、ReleaseDocs
和GitHubRelease
。请确保阅读 Releasing 以正确设置你的发布环境。
发布
git add .
git commit -m "Scaffold"
git remote add origin https://github.com/user/MyCoolNewLib.git
git push -u origin master
-
paket config add-token "https://nuget.net.cn" 4003d786-cc37-4004-bfdf-c4f3e8ef9b3a
- 或将环境变量
NUGET_TOKEN
设置为你的密钥
- 或将环境变量
-
- 您可以设置环境变量
GITHUB_TOKEN
来上传发布说明和文件到 GitHub - 否则将回退到用户名/密码
- 您可以设置环境变量
然后更新
CHANGELOG.md
中的 "未发布" 部分,其中包含本版本的发布说明,格式为 KeepAChangelog。
注意:强烈建议在受影响的发布说明旁边添加一个指向 Pull Request 的链接。这是因为当运行 RELEASE
目标时,它将把这些新注释添加到 git 提交的消息体中。GitHub 会注意到链接并更新 Pull Request,它会引用提交,例如说 "添加了一个引用此 pull request 的提交"。由于构建脚本自动化的提交消息,它会说 "将版本升到 x.y.z"。这样做的好处是,当用户访问 Pull Request 时,可以清楚地知道何时发布了哪些代码更改。另外,当阅读 CHANGELOG
时,如果有人对那些更改是如何或为什么被实施的感兴趣,他们可以很容易地发现工作和讨论。
这是将 "未发布" 部分添加到已发布 0.1.0
部分的 CHANGELOG.md
的示例。
## [Unreleased]
### Added
- Does cool stuff!
### Fixed
- Fixes that silly oversight
## [0.1.0] - 2017-03-17
First release
### Added
- This release already has lots of features
[Unreleased]: https://github.com/user/MyCoolNewLib.git/compare/v0.1.0...HEAD
[0.1.0]: https://github.com/user/MyCoolNewLib.git/releases/tag/v0.1.0
- 然后您可以使用
Release
目标,指定版本号,要么在RELEASE_VERSION
环境变量中,要么在目标名称后面作为参数。这会- 更新
CHANGELOG.md
,将更改从 "未发布" 部分移动到一个新的0.2.0
部分- 如果有任何 0.2.0 的预发布版本在变更日志中,它也会将这些更改收集到最终的 0.2.0 项中
- 提交提升版本:
提升版本到 0.2.0
并将新的变更日志部分添加到提交的消息体中 - 将包发布到 NuGet
- 推送 git 标签
- 为该 git 标签创建 GitHub 发布
- 更新
macOS/Linux 参数
./build.sh Release 0.2.0
macOS/Linux 环境变量
RELEASE_VERSION=0.2.0 ./build.sh Release
产品 | 版本 兼容的和额外的计算目标框架版本。 |
---|---|
.NET | net5.0 已计算。 net5.0-windows 已计算。 net6.0 兼容。 net6.0-android 已计算。 net6.0-ios 已计算。 net6.0-maccatalyst 已计算。 net6.0-macos 已计算。 net6.0-tvos 已计算。 net6.0-windows 已计算。 net7.0 已计算。 net7.0-android 已计算。 net7.0-ios 已计算。 net7.0-maccatalyst 已计算。 net7.0-macos 已计算。 net7.0-tvos 已计算。 net7.0-windows 已计算。 net8.0 已计算。 net8.0-android 已计算。 net8.0-browser 已计算。 net8.0-ios 已计算。 net8.0-maccatalyst 已计算。 net8.0-macos 已计算。 net8.0-tvos 已计算。 net8.0-windows 已计算。 |
.NET Core | netcoreapp2.0 已计算。 netcoreapp2.1 已计算。 netcoreapp2.2 已计算。 netcoreapp3.0 已计算。 netcoreapp3.1 已计算。 |
.NET Standard | netstandard2.0 兼容。 netstandard2.1 兼容。 |
.NET Framework | net461 已计算。 net462 已计算。 net463 已计算。 net47 已计算。 net471 已计算。 net472 已计算。 net48 已计算。 net481 已计算。 |
MonoAndroid | monoandroid 已计算。 |
MonoMac | monomac 已计算。 |
MonoTouch | monotouch 已计算。 |
Tizen | tizen40 已计算。 tizen60 已计算。 |
Xamarin.iOS | xamarinios 已计算。 |
Xamarin.Mac | xamarinmac 已计算。 |
Xamarin.TVOS | xamarintvos 已计算。 |
Xamarin.WatchOS | xamarinwatchos 已计算。 |
-
.NETStandard 2.0
- FSharp.Core (>= 6.0.1)
- Microsoft.Bcl.AsyncInterfaces (>= 6.0.0)
-
.NETStandard 2.1
- FSharp.Core (>= 6.0.1)
-
net6.0
- FSharp.Core (>= 6.0.1)
NuGet包 (3)
显示依赖于IcedTasks的顶级3个NuGet包
包名 | 下载 |
---|---|
FsToolkit.ErrorHandling.IcedTasks
FsToolkit.ErrorHandling 是一个基于 F# Result 类型的大量实用程序库,它允许一致的强大错误处理。 |
|
Migrondi.Core
这是 Migrondi CLI 的核心库,您可以使用此库将 Migrondi 的相同功能作为您的源代码的一部分,也可以用于编写对不同类型工具的抽象。 |
|
Hox
包描述 |
GitHub 存储库
此软件包未由任何流行的 GitHub 存储库使用。
版本 | 下载 | 最后更新 |
---|---|---|
0.11.7 | 648 | 7/11/2024 |
0.11.6 | 685 | 5/8/2024 |
0.11.5 | 2,951 | 4/22/2024 |
0.11.4 | 1,057 | 4/6/2024 |
0.11.3 | 489 | 2/7/2024 |
0.11.2 | 91 | 2/7/2024 |
0.11.0 | 548 | 1/31/2024 |
0.10.2 | 324 | 1/29/2024 |
0.10.0 | 14,209 | 11/22/2023 |
0.9.2 | 7,486 | 11/9/2023 |
0.9.1 | 100 | 11/8/2023 |
0.9.0 | 132 | 11/6/2023 |
0.8.5 | 729 | 10/29/2023 |
0.8.5-beta001 | 99 | 10/28/2023 |
0.8.4 | 121 | 10/28/2023 |
0.8.3 | 116 | 10/27/2023 |
0.8.2 | 344 | 10/23/2023 |
0.8.2-beta003 | 87 | 10/23/2023 |
0.8.0 | 2,345 | 7/18/2023 |
0.7.1 | 178 | 7/8/2023 |
0.7.0 | 5,180 | 7/4/2023 |
0.6.0 | 182 | 6/30/2023 |
0.6.0-beta001 | 123 | 6/30/2023 |
0.5.4 | 5,558 | 4/3/2023 |
0.5.4-beta004 | 123 | 4/3/2023 |
0.5.3 | 11,051 | 2/22/2023 |
0.5.1 | 3,047 | 12/17/2022 |
0.5.0 | 529 | 12/9/2022 |
0.5.0-beta001 | 119 | 12/9/2022 |
0.4.0 | 372 | 12/2/2022 |
0.3.2 | 328 | 12/1/2022 |
0.3.2-beta002 | 126 | 12/1/2022 |
0.3.2-beta001 | 110 | 12/1/2022 |
0.3.1 | 336 | 11/27/2022 |
0.3.1-beta002 | 125 | 11/27/2022 |
0.3.1-beta001 | 124 | 11/27/2022 |
0.3.0 | 1,314 | 11/8/2022 |
0.3.0-beta007 | 133 | 11/8/2022 |
0.3.0-beta006 | 133 | 11/8/2022 |
0.3.0-beta005 | 89 | 11/8/2022 |
0.3.0-beta004 | 92 | 11/8/2022 |
0.3.0-beta001 | 89 | 11/7/2022 |
0.2.0 | 38,070 | 3/23/2022 |
0.1.1 | 425 | 3/7/2022 |
0.1.0 | 528 | 3/6/2022 |
0.1.0-beta004 | 152 | 3/6/2022 |
0.1.0-beta003 | 152 | 3/6/2022 |
0.1.0-beta002 | 160 | 3/6/2022 |
0.1.0-beta001 | 155 | 3/6/2022 |
## [0.11.7] - 2024-07-10
[0.11.7]: https://github.com/TheAngryByrd/IcedTasks//compare/v0.11.6...v0.11.7
### 已修复
- [修复取消时不会发生释放操作](https://github.com/TheAngryByrd/IcedTasks/pull/50) - 感谢 @TheAngryByrd