我们无法将某些类型的任务合并到我们的产品和sprint积压工作中:
其中一些与项目没有直接关系,因此很容易将它们放在一边并将它们称为管理开销(从而减少sprint中可行的故事点).
然而,有些任务(通常是客户会议)经常发生或非常频繁.应如何处理?它们通常不直接与任何特定用户故事相关,但它们对项目至关重要.
假设我有一个保存到文件的异步方法:
async Task SaveToFileAsync()
{
var file = await folder.GetFileAsync ( ...)
var stream = file.OpenFileAsync(...)
///etc
}
Run Code Online (Sandbox Code Playgroud)
现在想象SaveToFileAsync同时被调用两次.这是一个问题,因为您无法同时在同一文件上写入
如果这是一个常规方法,lock()将解决这个问题:
void SaveToFile()
{
lock(something)
{
/// code here
}
}
Run Code Online (Sandbox Code Playgroud)
但是,异步方法中不允许锁定.
当然,可以调用Monitor.Enter()或使用互斥锁,但这些对象可以使用线程,而不是任务.因此他们不是答案.
因此,由于lock()不是一个选项,如何同步多个任务?特别是,我应该编写什么代码以确保一次只调用一次"SaveToFileAsync"?
我需要通过Rust程序中的posix filedescriptor读取外部进程提供的数据.fd连接保持很长时间(小时),另一方不时将数据传递给我.所以我需要不断地读取和处理数据流.
为此,我编写了一个循环,调用libc::read()(实际上是readv)来读取数据并在收到数据时对其进行处理.由于这会阻塞整个调度程序,因此我在新的调度程序(readv)上生成一个任务.只要它运行,这样就可以正常工作,但我找不到一种干净地关闭循环的方法.
由于循环在大多数时间都是阻塞的,所以我不能使用port/chan来通知循环退出.
我尝试通过使用失败的链接任务将其删除来杀死循环任务(生成监督的循环任务,在其中生成链接任务并等待端口上的信号发生,然后task::spawn_sched(SingleThreaded)用它来取消循环任务) .它在测试中运行良好,但fail!()不会中断(任务在读取完成之前不会失败,并且会libc::read()在某个时间点击.
我学到了很多关于libcore来源的知识,但我似乎找不到合适的解决方案.
task::yield()在Rust中似乎没有类似的东西吗?我能够在编译之前自动执行任务:
compile in Compile <<= (compile in Compile).dependsOn(myTask)
Run Code Online (Sandbox Code Playgroud)
如何在编译后做同样的事情?
我知道我能做到:
compile in Compile <<= (compile in Compile) map{x=>
// post-compile work
doFoo()
x
}
Run Code Online (Sandbox Code Playgroud)
执行任意Scala代码,但我需要在编译事件发生时自动执行目标任务
做类似的事情:
val foo = TaskKey[Unit]("foo", "...")
val fooTask = foo <<= scalaInstance map {si =>
...
} dependsOn(compile in Compile)
Run Code Online (Sandbox Code Playgroud)
如果我从sbt>提示符输入"foo",则可以正常工作; 即任务在编译后执行,但目标是挂钩到编译任务本身,因此无论何时编译发生,foo任务在编译完成后自动调用.
这是可能的,还是我以错误的方式处理内置编译任务?
在一个 易变的布尔字段上使用CancellationTokenSource来表示完成信号是否有任何好处?Task
我有这样的PowerShell脚本:
Foreach ($file in $files) {
[Do something]
[Do something]
[Do something]
}
Run Code Online (Sandbox Code Playgroud)
这样,一个文件将在另一个文件之后处理.我想同时处理4个文件.
我知道foreach -parallel循环,但是并行执行[do something]任务.我基本上想要并行运行整个foreach循环.
如何在PowerShell中实现这一目标?
考虑以下代码:
MyTask = LongRunningMethod(progressReporter, CancelSource.Token)
.ContinueWith(e =>
{ Log.Info("OnlyOnCanceled"); },
default,
TaskContinuationOptions.OnlyOnCanceled,
TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith(e =>
{ Log.Info("OnlyOnFaulted"); },
default,
TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith(e =>
{ Log.Info("OnlyOnRanToCompletion"); },
default,
TaskContinuationOptions.OnlyOnRanToCompletion,
TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith(e =>
{ Log.Info("None"); },
default,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)
当我使用提供的 CancelSource 取消任务时,输出为:
OnlyOnCanceled
None
正如预期的那样。
当 LongRunningMethod 抛出异常时,输出为:
OnlyOnFaulted
None
正如预期的那样。
当LongRunningMethod完成输出是:
None
所以ContinueWithwithTaskContinuationOptions.OnlyOnRanToCompletion没有像我期望的那样执行。
我检查MyTask.Status了最后一个ContinueWith分支,它仍然是Running. 因此,考虑到这一点,我希望跳过 OnlyOnRanToCompletion。问题是,为什么是Statusstill Running?查看调试输出,我可以看到它LongRunningMethod一直运行到最后。
var tasks = new List<Task>();
foreach (var guid in guids)
{
var task = new Task( ...);
tasks.Add(task);
}
foreach (var task in tasks)
{
task.Start();
Task.WaitAll(task);
}
Run Code Online (Sandbox Code Playgroud)
这是UI线程的运行.我需要一个接一个地执行任务变量中的所有任务.问题是如果我调用Task.WaitAll(任务),UI冻结.如何在不冻结UI的情况下执行以下逻辑?
using HttpServer
http = HttpHandler() do request::Request, response::Response
show(request)
Response("Hello there")
end
http.events["error"] = (client, error) -> println(error)
http.events["listen"] = (port) -> println("Listening on $port")
server = Server(http)
t = @async run(server, 3000)
Run Code Online (Sandbox Code Playgroud)
这会异步启动一个简单的小型Web服务器.问题是我不知道如何阻止它.我已经经历了朱莉娅的文件,并试图找到一些功能将会从队列(删除此任务kill,interrupt等),但似乎没有任何工作.
我怎么能杀掉这个任务?