Click here to Skip to main content
15,887,027 members
Home / Discussions / C#
   

C#

 
GeneralRe: File Transfer Queue Architecture Pin
Kevin Marois10-Nov-16 11:06
professionalKevin Marois10-Nov-16 11:06 
GeneralRe: File Transfer Queue Architecture Pin
Dave Kreskowiak10-Nov-16 15:30
mveDave Kreskowiak10-Nov-16 15:30 
GeneralRe: File Transfer Queue Architecture Pin
Kevin Marois11-Nov-16 5:42
professionalKevin Marois11-Nov-16 5:42 
GeneralRe: File Transfer Queue Architecture Pin
Gerry Schmitz11-Nov-16 6:30
mveGerry Schmitz11-Nov-16 6:30 
GeneralRe: File Transfer Queue Architecture Pin
Kevin Marois11-Nov-16 6:33
professionalKevin Marois11-Nov-16 6:33 
GeneralRe: File Transfer Queue Architecture Pin
Gerry Schmitz11-Nov-16 6:44
mveGerry Schmitz11-Nov-16 6:44 
GeneralRe: File Transfer Queue Architecture Pin
Dave Kreskowiak11-Nov-16 7:22
mveDave Kreskowiak11-Nov-16 7:22 
AnswerRe: File Transfer Queue Architecture Pin
Richard Deeming10-Nov-16 7:47
mveRichard Deeming10-Nov-16 7:47 
I'd be inclined to simplify that.

Start with a general-purpose async throttle, inspired by code from Stephen Toub's blog[^]:
C#
public sealed class Throttle
{
    private readonly Queue<TaskCompletionSource<IDisposable>> _waiters = new Queue<TaskCompletionSource<IDisposable>>();
    private readonly WaitCallback _releaseCoreCallback;
    private readonly Task<IDisposable> _releaserTask;
    private readonly Releaser _releaser;
    private readonly int _maxCount;
    private int _currentCount;

    public Throttle(int initialCount)
    {
        if (initialCount <= 0) throw new ArgumentOutOfRangeException();

        _maxCount = _currentCount = initialCount;

        _releaser = new Releaser(this);
        _releaserTask = Task.FromResult((IDisposable)_releaser);
        _releaseCoreCallback = ReleaseCore;
    }

    public Task<IDisposable> WaitAsync()
    {
        lock (_waiters)
        {
            if (_currentCount > 0)
            {
                // We have a spare slot - let the caller continue immediately:
                _currentCount--;
                return _releaserTask;
            }
            
            // The caller needs to wait for a slot to be released:
            var waiter = new TaskCompletionSource<IDisposable>();
            _waiters.Enqueue(waiter);
            return waiter.Task;
        }
    }

    private void Release()
    {
        TaskCompletionSource<IDisposable> toRelease = null;
        lock (_waiters)
        {
            if (_waiters.Count > 0)
            {
                // Another thread is waiting - let it continue now:
                toRelease = _waiters.Dequeue();
            }
            else if (_currentCount < _maxCount)
            {
                // Release the slot back to the pool:
                _currentCount++;
            }
            else
            {
                // Someone called "Dispose" twice:
                throw new SemaphoreFullException();
            }
        }
        
        if (toRelease != null)
        {
            // Release the next waiter on a background thread
            // to avoid a possible StackOverflowException:
            ThreadPool.QueueUserWorkItem(_releaseCoreCallback, toRelease);
        }
    }

    private void ReleaseCore(object state)
    {
        ((TaskCompletionSource<IDisposable>)state).SetResult(_releaser);
    }

    private sealed class Releaser : IDisposable
    {
        private readonly Throttle _throttle;

        public Releaser(Throttle throttle)
        {
            _throttle = throttle;
        }

        public void Dispose()
        {
            _throttle.Release();
        }
    }
}

That gives you a simple way to restrict the number of async methods which can access a resource simultaneously.

Your FTPQueue class then becomes:
C#
public static class FTPQueue
{
    private const int MAX_FILE_UPLOADS = 3;
    private static readonly Throttle UploadThrottle = new Throttle(MAX_FILE_UPLOADS);
    
    public static async Task FileReceived(string fileName)
    {
        Console.WriteLine("Received file {0}", fileName);
        
        using (await UploadThrottle.WaitAsync())
        {
            Console.WriteLine("Uploading file {0}", fileName);
            bool result = await TransferFile(fileName);
            if (result)
            {
                Console.WriteLine("Finished uploading {0}", fileName);
            }
            else
            {
                Console.WriteLine("Failed to upload {0}", fileName);
            }
        }
    }
    
    private static async Task<bool> TransferFile(string fileName)
    {
        await Task.Delay(10000);
        return true;
    }
}




"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer


GeneralRe: File Transfer Queue Architecture Pin
Kevin Marois10-Nov-16 7:49
professionalKevin Marois10-Nov-16 7:49 
QuestionShortcut key windows application C# Pin
Prabhanjant10-Nov-16 4:19
professionalPrabhanjant10-Nov-16 4:19 
AnswerRe: Shortcut key windows application C# Pin
OriginalGriff10-Nov-16 4:45
mveOriginalGriff10-Nov-16 4:45 
AnswerRe: Shortcut key windows application C# Pin
ZurdoDev10-Nov-16 4:45
professionalZurdoDev10-Nov-16 4:45 
QuestionRe: Shortcut key windows application C# Pin
Gerry Schmitz10-Nov-16 7:07
mveGerry Schmitz10-Nov-16 7:07 
QuestionCode of Decrease and increase for RichTextBox ? Pin
Member 24584679-Nov-16 22:49
Member 24584679-Nov-16 22:49 
AnswerRe: Code of Decrease and increase for RichTextBox ? Pin
Richard MacCutchan9-Nov-16 22:58
mveRichard MacCutchan9-Nov-16 22:58 
QuestionConfig-R and security Pin
Rob Philpott8-Nov-16 22:29
Rob Philpott8-Nov-16 22:29 
AnswerRe: Config-R and security Pin
Richard Deeming9-Nov-16 2:36
mveRichard Deeming9-Nov-16 2:36 
Questionhow to convery binary string to image Pin
Rıza Berkay Ayçelebi8-Nov-16 2:51
Rıza Berkay Ayçelebi8-Nov-16 2:51 
AnswerRe: how to convery binary string to image Pin
V.8-Nov-16 3:15
professionalV.8-Nov-16 3:15 
QuestionTheading with TCPListner Optimization Pin
maher khalil7-Nov-16 4:37
maher khalil7-Nov-16 4:37 
GeneralRe: Theading with TCPListner Optimization Pin
harold aptroot7-Nov-16 4:53
harold aptroot7-Nov-16 4:53 
GeneralRe: Theading with TCPListner Optimization Pin
maher khalil7-Nov-16 4:58
maher khalil7-Nov-16 4:58 
AnswerRe: Theading with TCPListner Optimization Pin
Paulo Zemek7-Nov-16 4:58
mvaPaulo Zemek7-Nov-16 4:58 
GeneralRe: Theading with TCPListner Optimization Pin
maher khalil7-Nov-16 5:04
maher khalil7-Nov-16 5:04 
GeneralRe: Theading with TCPListner Optimization Pin
maher khalil7-Nov-16 5:06
maher khalil7-Nov-16 5:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.