/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/IntegrationTest/New.IntegrationTests/InProcess/Helper.cs
117 строк
4 KB
Cyrus Najmabadi
Switch to using field+auto-prop
24 янв 2025, 11:26
24 янв 2025, 11:26
733debf
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using UIAutomationClient; namespace Roslyn.VisualStudio.IntegrationTests.InProcess; internal static class Helper { public static IUIAutomation2 Automation { get { if (field == null) { Interlocked.CompareExchange(ref field, new CUIAutomation8(), null); } return field; } } /// <summary> /// This method will retry the action represented by the 'action' argument, /// waiting for 'delay' time after each retry. If a given retry returns a value /// other than default(T), this value is returned. /// </summary> /// <param name="action">the action to retry</param> /// <param name="delay">the amount of time to wait between retries</param> /// <typeparam name="T">type of return value</typeparam> /// <returns>the return value of 'action'</returns> public static T? Retry<T>(Func<CancellationToken, T> action, TimeSpan delay, int retryCount = -1, CancellationToken cancellationToken = default) { return RetryHelper( cancellationToken => { try { return action(cancellationToken); } catch (COMException) { // Devenv can throw COMExceptions if it's busy when we make DTE calls. return default; } }, delay, retryCount, cancellationToken); } /// <summary> /// This method will retry the asynchronous action represented by <paramref name="action"/>, /// waiting for <paramref name="delay"/> time after each retry. If a given retry returns a value /// other than the default value of <typeparamref name="T"/>, this value is returned. /// </summary> /// <param name="action">the asynchronous action to retry</param> /// <param name="delay">the amount of time to wait between retries</param> /// <typeparam name="T">type of return value</typeparam> /// <returns>the return value of <paramref name="action"/></returns> public static Task<T?> RetryAsync<T>(Func<CancellationToken, Task<T>> action, TimeSpan delay, CancellationToken cancellationToken) { return RetryAsyncHelper( async cancellationToken => { try { return await action(cancellationToken); } catch (COMException) { // Devenv can throw COMExceptions if it's busy when we make DTE calls. return default; } }, delay, cancellationToken); } private static T RetryHelper<T>(Func<CancellationToken, T> action, TimeSpan delay, int retryCount, CancellationToken cancellationToken) { for (var i = 0; true; i++) { var retval = action(cancellationToken); if (i == retryCount) { return retval; } if (!Equals(default(T), retval)) { return retval; } Task.Delay(delay, cancellationToken).GetAwaiter().GetResult(); } } private static async Task<T> RetryAsyncHelper<T>(Func<CancellationToken, Task<T>> action, TimeSpan delay, CancellationToken cancellationToken) { while (true) { var retval = await action(cancellationToken).ConfigureAwait(true); if (!Equals(default(T), retval)) { return retval; } await Task.Delay(delay, cancellationToken).ConfigureAwait(true); } } }