草庐IT

关于c#:在父进程被杀死后完成异步任务

codeneng 2023-03-28 原文

Having an async task finish after parent process is killed

我正在尝试在 TFSBuild 完成后删除一个目录 (3gb)。我将任务放在 try finally 块中,以便它始终执行。问题是当手动停止构建时,如果需要 > 1 分钟左右,任务就会被终止。 TFSBuild 认为构建挂起,因为它需要很长时间才能停止。

我尝试了以下方法无济于事:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    static void Main(string[] args)
    {
        ThreadPool.QueueUserWorkItem(s => DeleteDir(@"C:\\292\\Sources", @"C:\\testdel\\del.bat"));
    }

    static void DeleteDir(string path, string batchDir)
    {
        var process = new Process
        {
            StartInfo =
            {
                Arguments = string.Format("{0}",
                                          path)
            }
        };

        process.StartInfo.FileName = batchDir;
        process.Start();
    }
}

这是批处理文件的内容:

1
del %1 /f /s /Q

我也尝试过使用 Directory.Delete 等。

TFSBuild 执行任务然后停止构建,但删除任务没有完成。如果我不称它为异步,那么它只会在 ~1 分钟后终止删除任务。

如何在父进程被杀死后执行这个删除任务?


诀窍是启动另一个进程来执行删除。 Powershell 是我的助手。

我有一个名为 Spawn-Cmd.ps1 的实用程序脚本,它为我创建了一个批处理文件并启动它。请注意,它也可以启动 exe 或其他 powershell 进程,但我使用批处理文件。

1
2
3
4
5
6
7
param([string]$cmdToSpawn)

$temp = [IO.Path]::GetTempFileName() + '.cmd'

Out-File -FilePath $temp -InputObject $cmdToSpawn -Encoding ASCII

Start-Process -FilePath $temp -WindowStyle Hidden

接下来修改您的 tfs 构建脚本以调用该脚本。这是一个示例 msbuild 文件。

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="utf-8"?>
<Project  DefaultTargets="SpawnDelete" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">

    <Target Name="SpawnDelete">
        <PropertyGroup>
            <Cmd>rd /s /q "z:\\path\\to\\folder"</Cmd>
        </PropertyGroup>

        <Exec Command="powershell -file Spawn-Cmd.ps1"$(Cmd)"" />
    </Target>
</Project>

无论 tfsbuild 进程发生什么,该命令都会运行完成。

请注意,这篇文章中还有一些其他选项可以实现这一点:MSBuild exec task without blocking

  • 决定使用每天一次删除已完成的构建文件夹的服务(由于简单性和我缺乏 powershell 知识)。但看起来你的答案可以很好地工作,所以我将其标记为答案:) 谢谢
  • 干杯!另外,我很高兴听到您有解决方案。

有关关于c#:在父进程被杀死后完成异步任务的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  3. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  4. ruby - 如何使用 RSpec::Core::RakeTask 创建 RSpec Rake 任务? - 2

    如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake

  5. ruby - 通过 ruby​​ 进程共享变量 - 2

    我正在编写一个gem,我必须在其中fork两个启动两个webrick服务器的进程。我想通过基类的类方法启动这个服务器,因为应该只有这两个服务器在运行,而不是多个。在运行时,我想调用这两个服务器上的一些方法来更改变量。我的问题是,我无法通过基类的类方法访问fork的实例变量。此外,我不能在我的基类中使用线程,因为在幕后我正在使用另一个不是线程安全的库。所以我必须将每个服务器派生到它自己的进程。我用类变量试过了,比如@@server。但是当我试图通过基类访问这个变量时,它是nil。我读到在Ruby中不可能在分支之间共享类变量,对吗?那么,还有其他解决办法吗?我考虑过使用单例,但我不确定这是

  6. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  7. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  8. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  9. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  10. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

随机推荐