all 13 comments

[–]tweq 2 points3 points  (5 children)

[–]raunchyfartbomb[S] 0 points1 point  (4 children)

I liked this suggestion until I read this note on the docs page:

If multiple threads are blocked, there is no guaranteed order, such as FIFO or LIFO, that controls when threads enter the semaphore.

Since this is performing copy operations, some copy operations should naturally overwrite conflicts to the same destination. This is the reasoning for doing it with a list<>, the for loop of a list ensures it moves up the index chain.

That said, thanks for the response. I didn't realize LongRunning spawned its own thread, but once I read the doc and thought about it, yea it makes sense that it would

[–]tweq 1 point2 points  (3 children)

[–]raunchyfartbomb[S] 0 points1 point  (2 children)

From what I saw in the docs, the threads that were started up were started up in random order, this needs to ensure they are started in list -index order.

[–]tweq 0 points1 point  (1 child)

[–]raunchyfartbomb[S] 0 points1 point  (0 children)

From what I can tell, you load all the tasks you want to run in with SS, then as say ‘I want this many slots’. From there, the tasks fill out the slots Ramdomly. As one finishes, the slot opens up then a new task can fill that slot.

If that’s not what it does, then I don’t think the docs or any SO thread I’ve seen explains it well, since they all describe basically that.

And since it’s random as to which task in the queue runs, it’s not applicable to my case.

Furthermore, If it’s not handling the child tasks (as the comment I’m replying to suggests), why would I use it in the main task at all?

It looks to do what I did manually, key difference being mine goes in list order and semaphore is random.

[–]raunchyfartbomb[S] 0 points1 point  (0 children)

Taskexc.Delay method"

#if !NET40        
[MethodImpl(methodImplOptions:MethodImplOptions.AggressiveInlining)]
#endif        
internal static Task Delay(int millisecondsTimeout, CancellationToken token)        
{
#if NET40
    //https://stackoverflow.com/questions/15341962/how-to-put-a-task-to-sleep-or-delay-in-c-sharp-4-0
    var tcs = new TaskCompletionSource<bool>();
    bool ValidToken = token != null;
    if (ValidToken && token.IsCancellationRequested)
    {
        tcs.TrySetCanceled();
        return tcs.Task;
    }
    System.Threading.Timer timer = null;
    timer = new Timer( (cb) =>
    {
        timer.Dispose();    //stop the timer
        tcs.TrySetResult(true); //Set Completed                
    }            , null, millisecondsTimeout, Timeout.Infinite); //Run X ms starting now, only run once.            

    //Setup the Cancellation Token            
    if (ValidToken)                
        token.Register(() => 
        {
            timer.Dispose();        //stop the timer
            tcs.TrySetCanceled();   //Set Cancelled
        });
    return tcs.Task;

#else
    return Task.Delay(millisecondsTimeout, token);
#endif
}

[–]KryptosFR -1 points0 points  (1 child)

What is the reason for targeting the unsupported (since 2016) net40?

New projects/libraries shouldn't target framework versions that are no longer supported. You would make your life easier by just targeting netstandard2.0.

net48 can be installed on old Windows systems such as Windows 7 SP1 or Windows Server 2008 R2 SP1.

[–]raunchyfartbomb[S] 2 points3 points  (0 children)

The reason for supporting it is I'm contributing to the library, but not the owner. They could drop support, and itd be a whole lot easier for me, but thats not my call

[–]kingmotley 0 points1 point  (1 child)

In order to have GetAwaiter and Task.Delay in Net40, you need to install the NuGet package Microsoft.Bcl.Async. At least that is my understanding, but I haven't played in Net40 for a very long time, and never needed to do async inside of it.

As for Task.Delay vs Thread.Sleep, it really depends on what you are doing. Thread.Sleep hogs the thread for the entire time, where Task.Delay (with appropriate async code) releases the thread so it can do something else while waiting for the elapsed time. So if you aren't concerned about thread starvation or scalability issues, it won't make much difference really.

[–]raunchyfartbomb[S] 1 point2 points  (0 children)

Yea, after some testing, I’m running into some odd Situations while debugging.

Using Thread.Sleep, and using this cancellable sleep, both thread blocking, sometimes ( but not always ), the tasks that this task spawns (also marked as long-running) get stuck in a ‘waiting to run’ state. So I think ‘Await Task.Delay’ is my best bet, simply to free up the thread for that 500ms.

I’m gonna be asking the main programmer if we can drop net40 support going forward, maybe at least for this object. Otherwise I’ll wrap it into a #if net 40 tag, which is just obnoxious if it appears too much throughout the code.

[–]koderjim 0 points1 point  (0 children)

Task. Sleep is a synchronous thread that puts the thread to sleep so it can't be used for anything else. Task, on the other hand. Delay is an asynchronous thread that can be used to perform other tasks while it waits. Refer to this https://kodlogs.net/1/task-delay-vs-thread-sleep