异步等待任务 使用多个项目完成超时

问题描述 投票:0回答:1

在高交易环境中进行测试给了我很多问题...我有一个过程,必须尽可能快地处理许多项目。我需要为每个过程指定最长的等待时间,这样即使我正在处理10个项目,每个项目也不会超过此时间。在每个过程中,我使用Http调用进行调用,并且还需要等待该结果。由于有Application Insights日志记录,因此尚未完成的进程仍然可以运行,我们希望报告这些项目的指标,这些指标在最大等待时间上花费时间。

[在这里阅读了asynchronously-wait-for-taskt-to-complete-with-timeout似乎可以接受的方法是使用asyc任务Task.Delay(cancellationToken)和Task.WhenAny。但是实际上,如果我超过3个项目,则Task.Delay永远不会触发,并且我的超时也不会发生。因此,我的总交易最大时间没有用完。

我在下面创建了单元测试。我会很感激对此问题的任何见解。

with these settings, I'd expect all of the tasks to complete because each one should finish fairly close to 500ms,
 the times are closer to 630ms but it usually finished

int howmany = 3
int maxTimeToWaitPerTaskMs = 750;
int pluginSleep = 500;

不是。

with these settings I'd expect all of the tasks to complete because each one should finish fairly close to 500ms, 
the times are closer to 1sec, which I don't understand at all, also means the Task.Delay did not seem to do it's job at all

int howmany = 5
int maxTimeToWaitPerTaskMs = 750;
int pluginSleep = 500;

不是。

[TestMethod()]
public async Task TestTaskTimeouts()
{
    List<int> list = new List<int>();
    for (int i = 0; i < 5; i++)
        list.Add(i);

    //mimic OrchestratorPerformance.MusicScore
    Stopwatch topWatch = Stopwatch.StartNew(); //start the activity watch
    try
    {
        List<Task> tasks = new List<Task>();
        foreach (var item in list)
        {
            //TimeSpan maxTimeout = TimeSpan.FromMilliseconds(maxTimeToWaitPerTaskMs);
            tasks.Add(Task.Factory.StartNew(() => FakeStepX(item, maxTimeToWaitPerTaskMs)));
            Thread.Sleep(25); //this is here because not having some time between Tasks seems to make things slower
        }

        //wait until all tasks report back.
        await Task.WhenAll(tasks.ToArray());
    }
    finally
    {
        topWatch.Stop();
        Trace.TraceInformation($"Top done: " + topWatch.Elapsed.TotalMilliseconds);
    }
}

/// <summary>
/// this process is blocking because I need to wait for the process to finish
/// </summary>
/// <param name="item"></param>
/// <param name="maxWaitMs"></param>
void FakeStepX(int item, int maxWaitMs)
{
    Stopwatch sw = Stopwatch.StartNew(); //start the activity watch
    try
    {
        //the given task
        Task<string> processStep = Task.Run(() =>
        {
            //force timeout
            return FakePluginRun(item).Result;
        });

        TimeSpan tsTimeout = TimeSpan.FromMilliseconds(maxWaitMs);
        using (var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMilliseconds(tsTimeout.Milliseconds + 100)))
        {
            var cancellationToken = cancellationTokenSource.Token;
            Task timerWithCancellation = Task.Delay(tsTimeout, cancellationToken);

            var task = Task.WhenAny(processStep, timerWithCancellation).Result;
            sw.Stop();
            if (task == processStep)
            {
                cancellationTokenSource.Cancel();
                Trace.TraceInformation($"{item}, completed: " + sw.Elapsed.TotalMilliseconds);
                string result = processStep.Result;
                return;
            }
            throw new TimeoutException();
        }
    }
    catch (AggregateException)
    {
        if (sw.IsRunning) sw.Stop();
        Trace.TraceInformation($"{item}, AggregateException: " + sw.Elapsed.TotalMilliseconds);
    }
    catch (TimeoutException)
    {
        if (sw.IsRunning) sw.Stop();
        Trace.TraceInformation($"{item}, timeout: " + sw.Elapsed.TotalMilliseconds);
    }
    finally
    {
        if (sw.IsRunning) sw.Stop();
    }
}

async Task<string> FakePluginRun(int item)
{
    //induce a specific time that this process will take
    int pluginSleep = 500;
    Task.Delay(pluginSleep).Wait();
    Trace.TraceInformation($"{item} slept");
    HttpResponseMessage result = await new HttpClient().GetAsync("http://bing.com");
    string json = await result.Content.ReadAsStringAsync();
    return "result text";
}

再次,非常感谢任何建设性的东西。这不是生产代码,但应产生结果。

btw我需要让50个项目正常工作或超时

在高交易环境中进行测试给了我很多问题...我有一个过程,必须尽可能快地处理许多项目。我需要每个过程的最大等待时间,即使...

asynchronous c#-4.0 multitasking
1个回答
0
投票

回答我自己的问题很尴尬,但有时您只需要吃乌鸦即可。

© www.soinside.com 2019 - 2024. All rights reserved.