Add 2 parameters to Start-ThreadJob: timeout seconds, priority · Issue #26 · PowerShell/ThreadJob · GitHub
Skip to content

Add 2 parameters to Start-ThreadJob: timeout seconds, priority #26

Open

Description

@kasini3000

Summary of the new feature / enhancement

Add 2 parameters to Start-ThreadJob: timeout seconds, priority

Proposed technical implementation details (optional)

priority:

A single asynchronous task has no timeout and no priority, It is very original.

The priority range is 1-9, and the default is 5,priority 1 will be executed first.


timeoutseconds:

For that things, I think thread-timeout is a good medicine:

like:
golang : “context.WithTimeout”
python : timeout* in threading lib

It is better to add a Boolean type of parameter : -AutoRemoveJob
whether to automatically remove threadjob after timeout,
parameter likes “receive-job -AutoRemoveJob”
In this way, users can only consider new thread and put ps1 script code.

both "ForEach-Object -Parallel" and "Start-ThreadJob" without timeout, This has seriously affected my development of "kasini3000" at present.

Powershell community do a "engine",i do a "car". the car is kasini3000 and k4t .
I love powershell. I want to give my opinion to the engine.
I hope the engine factory can transform a better engine.
I think timeoutseconds can make the ps1 script in the thread more robust.
I hope powershell will become stronger and stronger.

Activity

  1. rhubarb-geek-nz commented on Jan 29, 2023

    @rhubarb-geek-nz
    • “Shit-mountain-code”

    How does a timeout solve this? All you end up with is a section the task run and an indeterminate end state.

    • HANG

    If the thread is hung and unresponsive, you won't be able to cancel it with a cooperative cancellation mechanism (eg cancellation is an unwind performed in the thread). Preemptive termination leaves the process in an indeterminate state.

    • The regularity of unpredictable execution time.

    PowerShell is not a RTOS

    • Code executed remotely.

    Is the expectation that cancelling a local thread will also propagate to cancel remote threads, processes or any child local processes? What mechanism should be used to terminate a remote process?

    • memory leaks

    How does a timeouts solve memory leaks? If a thread is leaking memory and you stop it, it has still leaked memory, the memory won't be recovered. If the memory is recovered by the thread termination then it is not actually a leak, it is just memory usage.

    • cpu 100%

    100% CPU is not an issue if it is performing the required jobs. Cancelling a thread because you have high CPU just means you aren't performing the jobs you expected it to perform.

  2. rhubarb-geek-nz commented on Jan 29, 2023

    @rhubarb-geek-nz

    kasini3000 Are you able to implement timed thread cancellation in your own code?

    For example when you create a thread also create a CancellationToken and call CancellationTokenSource.CancelAfter to set your timeout. Then each thread has a cancellation token, use a static ThreadLocal<> to associate the thread token with each thread when they start.

    Where ever you have a loop, then also check the state of the CancellationToken associated with the current thread and if cancelled throw an exception. Likewise anywhere that you Thread.Sleep(timeout), do cancellationToken.WaitHandle.WaitOne(timeout) and again throw an exception if the cancellation has occurred.

    This could be implemented in a small C# class that you use in your PowerShell project.

  3. rhubarb-geek-nz commented on Jan 29, 2023

    @rhubarb-geek-nz

    Likewise, in the same module you can do

            Thread current = Thread.CurrentThread;
            current.Priority = ThreadPriority.BelowNormal;
    

    To adjust the priority.

  4. rhubarb-geek-nz commented on Jan 29, 2023

    @rhubarb-geek-nz

    The priority range is 1-9, and the default is 5,priority 1 will be executed first.

    Suggest use existing ThreadPriority enum

  5. rhubarb-geek-nz commented on Jan 30, 2023

    @rhubarb-geek-nz

    This is a pattern you can use now and also on original non-core PowerShell.exe

    $cancellationTokenSource = New-Object -Type System.Threading.CancellationTokenSource
    
    try
    {
    	$cancellationTokenSource.CancelAfter(5000)
    	$cancellationToken = $cancellationTokenSource.Token
    
    	[Threading.Thread]::CurrentThread.Priority = [Threading.ThreadPriority]::BelowNormal
    
    	Write-Host $cancellationToken.IsCancellationRequested
    
    	$result = $cancellationToken.WaitHandle.WaitOne(10000)
    
    	Write-Host $result
    }
    finally
    {
    	$cancellationTokenSource.Dispose()
    }
    
  6. kasini3000 commented on Feb 2, 2023

    @kasini3000
    Author

    timeoutseconds can make the ps1 script in the thread more robust.
    The example you share is very important to the powershell community and USERS !!!
    thanks rhubarb-geek-nz !!!

    I hope ANYONE can provide PR as soon as possible to realize this function

  7. kborowinski commented on Feb 21, 2023

    @kborowinski

    rhubarb-geek-nz Could you show a small example how to use ThreadLocal with cancelation token inside of the Start-ThreadJob scriptblock?

  8. rhubarb-geek-nz commented on Feb 21, 2023

    @rhubarb-geek-nz

    The more I look at PowerShell threads the more I think it is better to forget about them actually being threads. I may be completely wrong about this but PowerShell threads are completely isolated from other threads, this is unlike a traditional threading system where threads share memory. Here it appears that threads use their own runspace and are isolated from others. From my tests, even $Global are not global, they seem effectively visible only with that thread/runspace.
    So within a thread script block you might as well just pass the token around as a variable or put it in $Global.
    This does mean you can use exactly the same mechanism for jobs that run in other processes or on other machines.
    Rather than think about it as job cancellation or job timeout, think of it in terms of what are the conditions under which my job will terminate. The token is then just part of the calculation.

  9. rhubarb-geek-nz commented on Feb 21, 2023

    @rhubarb-geek-nz

    That said, if they are threads running in the same process you might be able to pass a cancellation token created in the main thread or any other thread onto another thread via argument list into the parameters of a script block. This would not work for jobs in other process or remote jobs.

  10. kasini3000 commented on Apr 4, 2023

    @kasini3000
    Author

    stevenebutler
    I saw you adding a cancellation token to IWR. Do you have time to address this issue?

  11. kasini3000 commented on Apr 12, 2023

    @kasini3000
    Author

    news:asp.net8 pr3 add timeout for per request

    https://devblogs.microsoft.com/dotnet/asp-net-core-updates-in-dotnet-8-preview-3/

    You can set request timeouts for individual endpoints, controllers, or dynamically per request.

    To apply request timeouts, first add the request timeout services:

    builder.Services.AddRequestTimeouts();
    You can then apply request timeouts using middleware by calling :UseRequestTimeouts()

  12. stevenebutler commented on Apr 16, 2023

    @stevenebutler

    stevenebutler I saw you adding a cancellation token to IWR. Do you have time to address this issue?

    I don't really know much about this side of PowerShell so I don't think I can help here. If I read the issue correctly (and I may not) you are looking for something to cancel jobs that are running after a timeout.

    If that's the case I don't think cancellation tokens are going to help you because they rely on the code being cancelled being co-operative in that it must periodically check for cancellation. If you're stuck inside third party code that does not use/check a cancellation token then it will not take any notice of the cancellation of the token and will continue to process until it finishes. The fix I applied was to make the code base in IWR (which we control) more co-operative by checking the cancellation token in places where it was not.

  13. kasini3000 commented on Apr 17, 2023

    @kasini3000
    Author

    it must periodically check for cancellation.

    sounds good.
    1 Add an attribute to the job: endtime. The value is the current time plus [timespan] 'sometime'
    2 Then regularly reduce the inspection and cancel it.


    If you're stuck inside third party code that does not use/check a cancellation token then it will not take any notice of the cancellation of the token and will continue to process until it finishes.

    Can the job be placed in a subfunction that enforces the use of a cancel token?
    There seems to be a saying that forces the insertion of a sleep some millisecond in the powershell job code. Canceling the token will be executed.

  14. stevenebutler commented on Apr 19, 2023

    @stevenebutler

    The only way I know of to deal with an uncancellable job is to do one of the following

    • terminate the process (if running out of process);
    • terminate the thread running it (very unreliable and causes major issues with stability and probably not even possible if it's a C# Task based job); or
    • run it in a background task and just leave it running but give up waiting for the outcome once it goes past its timeout. This is obviously not ideal because the job will continue to consume resources but you no longer care about the outcome.

    If you're trying to cancel arbitrary code, the safest way to do it is to run it in a separate process and terminate that once the timeout is reached. You should be able to do this already using start-job and related cmdlets.

  15. kasini3000 commented on Apr 19, 2023

    @kasini3000
    Author

    If you're trying to cancel arbitrary code, the safest way to do it is to run it in a separate process and terminate that once the timeout is reached

    Even if you don't want to help PR, don't say that.
    IWR's timeout does not start a new process and can also terminate threads.
    no new thread in IWR ?i don‘t know.

    The thread must be able to be terminated. this issue only want adding a timeout-- If a thread may never be terminated, who dares to use it?


    golang : “context.WithTimeout”
    python : timeout* in threading lib

    this issue force me to use Python or Golang

  16. 13 remaining items

  17. kasini3000 commented on Apr 28, 2023

    @kasini3000
    Author

    The process can hang, so someone invented the kill command.
    Your computer can hang, so someone invented the reset key.
    Next, go to glibc and find a way to stop the thread.
    I eat every day, cook often, and it's a common thing to remove rotten leaves from a vegetable. (I allow the loss of some good leaves, just like allowing thread termination to allow a small amount of data loss.)
    Well, leave foolishness and find a way out.

  18. rhubarb-geek-nz commented on Apr 28, 2023

    @rhubarb-geek-nz

    The process can hang, so someone invented the kill command.

    First computers could only run on program at a time. Later computers supported processes to varying levels of degree to allow multiple programs to run on the expensive hardware.

    If you do not have pre-emptive multi-tasking and memory protection then all other processes are at risk from the worst program. Compare Windows 3.1 to OS/2, or Windows 95 to Windows NT, the system with process and kernel isolation and strong memory protection provides the most reliable system. Consider Windows 3.1, Windows 95 and any Macintosh System below 10 were absolutely terrible in terms of process isolation. Programming errors could cause memory corruption in any process.

    The game changer in reliability of systems was the introduction of virtual memory, preemptive multitasking and memory protection. So as you mentioned the kill command. The killing of processes is incredibly efficient because there is no cleanup of the process to be done. All that happens is the open file handles are closed, the memory for the entire process marked as available and a signal raised to indicate the process is finished.

    Now if you look at how UNIX shells operate, they don't need to use threads to achieve efficient pipelines and parallelism. They work using fork and copy-on-write, so rather than creating a thread the entire process is cloned and two versions of the same program run using the same memory but with memory protection between them. Only on memory-write is new memory allocated to manage the difference in memory state on a page by page basis. Either could terminate and the other would be unaffected, except for the SIGCHLD signal going to the parent.

    Threading in a single process is much harder. It is hard to write robust preemptive multithreading code. It is hard when you write the entire program, it is even harder when you then include 3rd party code into your process which does not abide by the rules.

    So I will keep mentioning why TerminateThread is so bad, it completely trashes your ability to maintain a consistent memory image. Let's ask Raymond what happens when a thread is terminated and it releases a mutex. Spoiler, you’re in big trouble.

    The TerminateThread does not care if you are running PowerShell script, C# code or native C or C++ code. It will terminate it all without giving the code the opportunity to either protect itself or clean up.

    If you want to put this in perspective, this is an ideal way to corrupt an SQLite database. The updates to the database were taking too long so terminate the thread! You risk corrupting the structures used to manage the data and transaction control.

    In the POSIX world pthread_cancel is used terminate a thread. The way that code protects itself from this is using pthread_setcancelstate to protect critical sections. In this case the value of PTHREAD_CANCEL_DISABLE will prevent the cancellation from occurring. This is again a cooperative model, pthread_cancel simply marks that a thread should terminate but requires the thread to perform the termination itself by exiting.

  19. rhubarb-geek-nz commented on Apr 29, 2023

    @rhubarb-geek-nz

    PowerShell is often compared to python, both high level scripting languages. Let's see what they have to say about it...

    https://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread

    It is generally a bad pattern to kill a thread abruptly, in Python, and in any language.

    Exactly the same story.

    A good usage pattern of this code is to have the thread catch a specific exception and perform the cleanup. That way, you can interrupt a task and still have proper cleanup.

    Exactly what we are saying with cooperative threads.

  20. rhubarb-geek-nz commented on May 12, 2023

    @rhubarb-geek-nz

    Another approach that you can do yourself is to create a cancellation token to define the time a thread should take and then use Register-ObjectEvent to register a handler to terminate the job.

    You need an actual dotnet class with an event that can be used by Register-ObjectEvent, this also registers an Action delegate with the cancellation token.

    Add-Type -Language CSharp @"
    using System;
    using System.Threading;
    namespace RhubarbGeekNz
    {
    	public class CancellationEvent : IDisposable
    	{
    		public event Action Cancelled;
    		public void Dispose() => Token.Dispose();
    		private readonly IDisposable Token;
    		public CancellationEvent(CancellationToken ct)
    		{
    			Token = ct.Register(()=>Cancelled());
    		}
    	}
    }
    

    Create your thread as normal

    $job = Start-ThreadJob -ScriptBlock {
    	try
    	{
    		Write-Output 'thread start'
    		Start-Sleep -Seconds 30
    		Write-Output 'thread complete'
    	}
    	finally
    	{
    		Write-Output 'thread finally'
    	}
    }
    

    Now set up the cancellation token to expire after 5000 milliseconds

    $cancellationTokenSource = New-Object -Type System.Threading.CancellationTokenSource
    $cancellationTokenSource.CancelAfter(5000)
    $cancellationToken = $cancellationTokenSource.Token
    

    Set up the objects to connect the cancellation token to generate a PowerShell event for that job

    $cancellationEvent = New-Object -Type RhubarbGeekNz.CancellationEvent -ArgumentList $cancellationToken
    Register-ObjectEvent -InputObject $cancellationEvent -EventName 'Cancelled' -SourceIdentifier 'CancellationToken' -MessageData $job
    

    Now wait for the event and stop the associated job, the job identifier comes from the event MessageData. The Sender is the $cancellationEvent.

    $event = Wait-Event -SourceIdentifier 'CancellationToken'
    Stop-Job -Job $event.MessageData
    $event.Sender.Dispose()
    Remove-Event -EventIdentifier $event.EventIdentifier
    

    And get the result of the terminated job

    $job | Receive-Job -Wait -AutoRemoveJob
    

    So those are the building blocks, it shows you can manage both remote and local jobs with your own timeout mechanism.

  21. rhubarb-geek-nz commented on May 12, 2023

    @rhubarb-geek-nz

    You could implement the stop-job within the action of the object event.

    $null = Register-ObjectEvent -InputObject $cancellationEvent -EventName 'Cancelled' -MessageData $job -Action {
    	Stop-Job -Job $Event.MessageData
    	$Event.Sender.Dispose()
    	Remove-Event -EventIdentifier $Event.EventIdentifier
    	New-Event -Sender $Event.Sender -SourceIdentifier 'CancellationToken' -MessageData $Event.MessageData
    }
    

    I find you still need Wait-Event to be running to process the event queue. The New-Event is to unblock the waiting Wait-Event.

  22. rhubarb-geek-nz commented on May 13, 2023

    @rhubarb-geek-nz

    See github and PSGallery for module to create the event registration

  23. rhubarb-geek-nz commented on May 19, 2023

    @rhubarb-geek-nz

    Have updated the above package to let you cancel a ScriptBlock

    $cancellationTokenSource = New-Object -Type System.Threading.CancellationTokenSource
    $cancellationTokenSource.CancelAfter(5000)
    $cancellationToken = $cancellationTokenSource.Token
    
    Invoke-CommandWithCancellationToken -ScriptBlock {
        Wait-Event
    } -CancellationToken $cancellationToken -NoNewScope
    
  24. rhubarb-geek-nz commented on May 21, 2023

    @rhubarb-geek-nz

    kasini3000 example of using a cancellation token to implement a thread timeout

    $ErrorActionPreference = 'Stop'
    $cancellationTokenSource = New-Object -Type System.Threading.CancellationTokenSource
    $cancellationTokenSource.CancelAfter(5000)
    
    try
    {
    	$job = Start-ThreadJob -ScriptBlock {
    		param([System.Threading.CancellationToken]$cancellationToken)
    		Invoke-CommandWithCancellationToken -ScriptBlock {
    			try
    			{
    				'begin job'
    				Wait-Event
    				'end job'
    			}
    			finally
    			{
    				'finally job'
    			}
    		} -CancellationToken $cancellationToken -NoNewScope
    	} -ArgumentList $cancellationTokenSource.Token -Name 'CancelExample'
    
    	$job
    
    	$job | Wait-Job
    
    	$job | Receive-Job
    }
    finally
    {
    	$cancellationTokenSource.Dispose()
    }
    

    Result is

    Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
    --     ----            -------------   -----         -----------     --------             -------
    1      CancelExample   ThreadJob       NotStarted    False           PowerShell           …
    1      CancelExample   ThreadJob       Completed     True            PowerShell           …
    begin job
    finally job
    Invoke-CommandWithCancellationToken: 
    Line |
       3 |          Invoke-CommandWithCancellationToken -ScriptBlock {
         |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         | The operation was canceled.
    

    Multiple threads can share the same cancellation token, so create a single cancellation token to be cancelled after 5 minutes and start twenty threads using the same cancellation token, then all will be cancelled in 5 minutes.

    With the PSGallery module I published you can do that right now.

  25. rhubarb-geek-nz commented on May 21, 2023

    @rhubarb-geek-nz

    Refer to Golang's approach : WithTimeout https://github.com/golang/go/blob/master/src/context/context.go

    Golang's approach is still cooperative.

    // A CancelFunc tells an operation to abandon its work.
    // A CancelFunc does not wait for the work to stop.
    

    Go will still panic and stop the process if things are not in order.

    https://forum.golangbridge.org/t/why-does-go-terminate-the-whole-process-if-one-goroutine-paincs/27122

  26. rhubarb-geek-nz commented on May 21, 2023

    @rhubarb-geek-nz

    This example creates one cancellation token with cancels after 5000ms. The same token is passed to 6 threads, they are all cancelled at the same time

    $ErrorActionPreference = 'Stop'
    $cancellationTokenSource = New-Object -Type System.Threading.CancellationTokenSource
    $cancellationTokenSource.CancelAfter(5000)
    
    try
    {
    	$jobs = @()
    
    	[int32]$i = 0
    
    	while ( $i -le 5)
    	{
    		$job = Start-ThreadJob -ScriptBlock {
    			param([System.Threading.CancellationToken]$cancellationToken)
    			Invoke-CommandWithCancellationToken -ScriptBlock {
    				try
    				{
    					'begin job'
    					Wait-Event
    					'end job'
    				}
    				finally
    				{
    					'finally job'
    				}
    			} -CancellationToken $cancellationToken -NoNewScope
    		} -ArgumentList $cancellationTokenSource.Token -Name "CancelExample $i"
    
    		$jobs += $job
    
    		$i += 1
    	}
    
    	$jobs
    
    	foreach ($job in $jobs)
    	{
    		$job | Wait-Job
    	}
    
    	foreach ($job in $jobs)
    	{
    		try
    		{
    			$job | Receive-Job
    		}
    		catch
    		{
    			$PSItem.Exception.Message
    		}
    	}
    }
    finally
    {
    	$cancellationTokenSource.Dispose()
    }
    

    Output is

    Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
    --     ----            -------------   -----         -----------     --------             -------
    1      CancelExample 0 ThreadJob       NotStarted    False           PowerShell           …
    2      CancelExample 1 ThreadJob       NotStarted    False           PowerShell           …
    3      CancelExample 2 ThreadJob       NotStarted    False           PowerShell           …
    4      CancelExample 3 ThreadJob       NotStarted    False           PowerShell           …
    5      CancelExample 4 ThreadJob       NotStarted    False           PowerShell           …
    6      CancelExample 5 ThreadJob       NotStarted    False           PowerShell           …
    1      CancelExample 0 ThreadJob       Completed     True            PowerShell           …
    2      CancelExample 1 ThreadJob       Completed     True            PowerShell           …
    3      CancelExample 2 ThreadJob       Completed     True            PowerShell           …
    4      CancelExample 3 ThreadJob       Completed     True            PowerShell           …
    5      CancelExample 4 ThreadJob       Completed     True            PowerShell           …
    6      CancelExample 5 ThreadJob       Completed     True            PowerShell           …
    begin job
    finally job
    The operation was canceled.
    begin job
    finally job
    The operation was canceled.
    begin job
    finally job
    The operation was canceled.
    begin job
    finally job
    The operation was canceled.
    begin job
    finally job
    The operation was canceled.
    The operation was canceled.
    
  27. Zetanova commented on Apr 2, 2024

    @Zetanova

    Is there any good solution to call a .net async method with cancellation?
    I want to be able to cancel ctrl+c a StreamReader.ReadLineAsync

    Nothing seams to work, beside to kill the pwsh instance.

    The reader will be later inside a Start-ThreadJob,
    but it is very inconvenient not to create/debug in the main runspace.

    $TypeDefinition = @'
    using System;
    using System.Threading;
    
    public class HttpClientHandlers
    {
        public static CancellationTokenSource GetConsoleCts() {
            var cts = new CancellationTokenSource();
            
            System.ConsoleCancelEventHandler handler = null;
            handler = (sender, e) => {
                //e.Cancel = true;
                cts.Cancel();
                if(handler is not null) {
                    Console.CancelKeyPress -= handler;
                    handler = null;
                }
            };
            Console.CancelKeyPress += handler;
            return cts;
        }
    }
    '@
    Add-Type -TypeDefinition $TypeDefinition
    
    $cts = [HttpClientHandlers]::GetConsoleCts()
    #...
    $reader = new-object System.IO.StreamReader($stream)
    
    while(!$reader.EndOfStream) {
        $line = $reader.ReadLineAsync($cts.Token).GetAwaiter().GetResult()
        Write-Host $line
    }
    Write-Host "end"
  28. rhubarb-geek-nz commented on Apr 3, 2024

    @rhubarb-geek-nz

    Unfortunately PowerShell is not really task/async/await aware. Within a cmdlet it relies on thread local storage for context.

    I would suggest that within a cmdlet you create a child thread (not with ThreadJob) run your async tasks from that and wait on an event in your cmdlet that you indicate all your async tasks are finished and then return.

    It isn't safe to call PSCmdlet.WriteObject for instance from within a task that has lost all connection with the thread that PowerShell called your cmdlet's methods on.

    An alternative would be to use rhubarb-geek-nz.CancellationTokenEvent/ and use Invoke-CommandWithCancellationToken to call Invoke-WebRequest, that would keep all your code in PowerShell.

  29. Zetanova commented on Apr 4, 2024

    @Zetanova

    rhubarb-geek-nz thx, for your help and input.

    Because the lack of support from Invoke-WebRequest for HttpRequest streaming and WebSockets. I am forced to use the dotnet Types & instances.

    I can query and execute commands to the Kubernetes API without any 3th party compiled assemblies from the pwsh 7.4
    without spawning any child-processes for 70mb memory each.

    The issue persist that currently the pwsh Runspace/Host does not provide any native Signal/WaitHandle/Callback to abort an operation.

    To call sync-over-async method in a STA environment will always produce a lock, but it does not mean that the inside async-method can not be cancelled with over a CancellationToken

    Something like this would already useful in many await/async situations.

    $ct = $Host.Runspace.Aborted
    $line = $reader.ReadLineAsync($ct).GetAwaiter().GetResult()

    or something like the new ForEach-Object -Parallel where $MyCancellation would be a well-known variable that gets cancelled on Pipe.StopAsync()

    $lines = Invoke-Pipe {
        $reader = $using:reader
        $ct = $MyCancellation
        while(!$reader.EndOfStream) {
            $line = $reader.ReadLineAsync($MyCancellation).GetAwaiter().GetResult()
            Write-Output $line
        }
    }
  30. rhubarb-geek-nz commented on Apr 4, 2024

    @rhubarb-geek-nz

    The issue persist that currently the pwsh Runspace/Host does not provide any native Signal/WaitHandle/Callback to abort an operation.

    Agreed, I suggested that Common Parameters should include a CancellationToken.

    Signals don't really fit with my idea of PowerShell, they are process owned, where as I see the point of PowerShell is to write small reusable scripts, modules, functions and cmdlets that do not own the process and are then assembled for some higher purpose to solve a problem.

    My theory is that the PowerShell host itself should have the signal handler and the root console interactive session or script gets a cancellation token that will be tripped by that.

    Good luck with your solution, sounds fun.

    I wrote an ASP web server that uses HttpContext.RequestAborted to call PowerShell.StopAsync when a response was no longer worthwhile as the client had disconnected.

  31. Zetanova commented on Apr 4, 2024

    @Zetanova

    I found a method to get the SIGINT signal (windows and linux) from the pwsh.exe to be useable for sync-over-async calls on Runspace1. https://gist.github.com/Zetanova/9e1a0d5e35d9ce876840b9d9b22445b3

    It can be used in dotnet async method calls to be able to cancel them like with the pipe StopProcessing behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions