найти детали незавершенных задач из списка - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть функция рекурсивного спуска, которая берет все файлы из родительского каталога и все файлы из любого числа дочерних каталогов для отправки в AWS S3. У меня есть 5-минутный таймаут, на основе этого поста , настроенный на то, чтобы все файлы в папке были перенесены на S3, и если это займет больше времени, я хочу отменить любую из оставшихся задач. Пока я устанавливаю флаг отмены для токена, независимо от того, истек ли тайм-аут Delay или Wait из WhenAny, я хочу иметь возможность взять все задачи, которые не были выполнены из списка и вытащить детали запроса на регистрацию. Microsoft утверждает, что Id и CurrentId задачи нельзя считать уникальными.

Как получить объект запроса, который создал задачу, из объекта задачи?

private static void ProcessDirectory(System.IO.DirectoryInfo di)
{
    int _timeOut = 5 * 60 * 1000;
    foreach (var item in di.GetDirectories())
    {
        ProcessDirectory(item);
    }

    using (Amazon.S3.AmazonS3Client _client = new Amazon.S3.AmazonS3Client())
    {
        System.Threading.CancellationTokenSource _cancellationTokenSource = new System.Threading.CancellationTokenSource();
        System.Collections.Generic.List<System.Threading.Tasks.Task<Amazon.S3.Model.PutObjectResponse>> _responses = new List<System.Threading.Tasks.Task<Amazon.S3.Model.PutObjectResponse>>(1000);
        foreach (var item in di.GetFiles())
        {
            _responses.Add(_client.PutObjectAsync(new Amazon.S3.Model.PutObjectRequest
            {
                BucketName = SiteSettings.Bucket,
                CannedACL = Amazon.S3.S3CannedACL.PublicRead,
                FilePath = item.FullName,
                Key = item.FullName.Replace(SiteSettings.OutputRoot, string.Empty).Replace(@"\", "/")
            }, _cancellationTokenSource.Token));                    
        }
        // Wait 5 Mins + 1 sec
        System.Threading.Tasks.Task.WhenAny(System.Threading.Tasks.Task<Amazon.S3.Model.PutObjectResponse>.WhenAll(_responses)
            , System.Threading.Tasks.Task.Delay(_timeOut)).Wait(_timeOut + 1000);

        _cancellationTokenSource.Cancel(); //Cancel the remaining pushes for this folder.
        foreach (var item in _responses)
        {
            if (!item.IsCompleted)
            {
                //Pull the key value to log
            }
        }
    }
}

1 Ответ

0 голосов
/ 05 сентября 2018

Вы можете сохранить уникальный ключ для каждого рабочего элемента после его создания, а затем использовать этот ключ для регистрации. В этом примере я использовал item.FullName в качестве ключа. Также я позволил себе удалить длинные пространства имен перед типами для лучшей читабельности, надеюсь, вы не будете возражать:

private static void ProcessDirectory(System.IO.DirectoryInfo di)
{
    int _timeOut = 5 * 60 * 1000;
    foreach (var item in di.GetDirectories())
    {
        ProcessDirectory(item);
    }

    using (Amazon.S3.AmazonS3Client _client = new Amazon.S3.AmazonS3Client())
    {
        CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
        Dictionary<string, Task<Amazon.S3.Model.PutObjectResponse>> _responses =
            new Dictionary<string, Task<Amazon.S3.Model.PutObjectResponse>>(1000);

        foreach (var item in di.GetFiles())
        {
            // use any unique information about your item here
            var itemName = item.FullName;
            _responses[itemName] = _client.PutObjectAsync(new Amazon.S3.Model.PutObjectRequest
            {
                BucketName = SiteSettings.Bucket,
                CannedACL = Amazon.S3.S3CannedACL.PublicRead,
                FilePath = itemName,
                Key = item.FullName.Replace(SiteSettings.OutputRoot, string.Empty).Replace(@"\", "/")
            }, _cancellationTokenSource.Token);
        }
        // Wait 5 Mins + 1 sec
        Task.WhenAny(Task<Amazon.S3.Model.PutObjectResponse>.WhenAll(_responses.Values)
            ,Task.Delay(_timeOut)).Wait(_timeOut + 1000);

        _cancellationTokenSource.Cancel(); //Cancel the remaining pushes for this folder.
        foreach (var item in _responses)
        {
            if (!item.Value.IsCompleted)
            {
                //Pull the key value to log
                var keyValue = item.Key;
            }
        }
    }
}

Видите ли, я обменял List<Task<Amazon.S3.Model.PutObjectResponse>> на Dictionary<string, Task<Amazon.S3.Model.PutObjectResponse>>, где ключ - полное имя файла. Поэтому, если какое-либо задание в словаре не завершится через 5 минут, вы сможете получить имя файла, который не был загружен.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...