使用非参数委托初始化线程字段初始值设定项

时间:2017-05-25 07:55:39

标签: c# multithreading

这听起来像一个愚蠢的问题,但我被困了一段时间。

有什么想法?

  • 我希望有一个在后台工作的线程和我 想要重复使用它,因为它每次都会做同样的工作。
  • 我知道创建新线程可能会带来很多开销 CPU(私有局部变量堆栈分配)每个线程消耗1 记忆的MB,所以我不希望这样。

到目前为止我有什么。

我有动作过滤器,它在每次执行web api控制器方法之前和之后都做了一些工作。在我的情况下,这是编写统计信息,因此我不想初始化新的Thread实例。这是我的代码:

public sealed class AnalyzeActionFilterAttribute : ActionFilterAttribute
{
    private const string Key = "__action_duration__";
    private static Thread _worker = new Thread {IsBackground = true}; -- this doesnt compile because Thread class doesn't have parameterless constructor.

    /// <inheritdoc />
    /// <summary>
    ///     Starts timer and adds statistics per action in Web Api Controllers.
    /// </summary>
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var stopWatch = new Stopwatch();
        var actionName = actionContext.ActionDescriptor.ActionName;

        StatisticsProvider.Instance.AddTotalCalls(actionName);

        actionContext.Request.Properties[Key] = stopWatch;
        stopWatch.Start();

        base.OnActionExecuting(actionContext);
    }

    /// <inheritdoc />
    /// <summary>
    ///     Stops timer after finishing execution of action and adds statistics for this action.
    /// </summary>
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        new Thread(() =>
        {
            Thread.CurrentThread.IsBackground = true;
            PopulateStatistics(actionExecutedContext);
        }).Start();
    }

    private static void PopulateStatistics(HttpActionExecutedContext actionExecutedContext)
    {
        var actionName = actionExecutedContext.ActionContext.ActionDescriptor.ActionName;

        if (!actionExecutedContext.Request.Properties.ContainsKey(Key)) { return; }
        if (actionExecutedContext.Exception != null)
        {
            StatisticsProvider.Instance.AddToFailedCalls(actionName);
            return;
        }

        var stopwatch = actionExecutedContext.Request.Properties[Key] as Stopwatch;

        if (stopwatch != null)
        {
            stopwatch.Stop();
            StatisticsProvider.Instance.AddToTotalTime(actionName, stopwatch.Elapsed);
            StatisticsProvider.Instance.CheckForMinCallTime(actionName, stopwatch.Elapsed);
            StatisticsProvider.Instance.CheckForMaxCallTime(actionName, stopwatch.Elapsed);
        }

        if (actionExecutedContext.Response.StatusCode != HttpStatusCode.OK)
        {
            StatisticsProvider.Instance.AddToFailedCalls(actionName);
        }

        StatisticsProvider.Instance.CalculateAvgTotalTime(actionName);
        StatisticsProvider.Instance.ChangeLastProcessDate(actionName, DateTime.UtcNow);
    }

}

我有什么问题?

  • 如何编写具有参数的静态线程字段初始化程序调用方法?我想从OnActionExecuted方法中删除代码,只需调用字段线程的Start()方法。
  • 这是值得一试或创建新线程并让线程调度程序处理开销,因为我也不想编写大量的样板代码。

0 个答案:

没有答案