【问题标题】:Add Delay to Async Thread Start Based on Server Load根据服务器负载为异步线程启动添加延迟
【发布时间】:2018-06-13 01:25:54
【问题描述】:

我有一个查询本地数据库并将其发布到 Web api 的任务。目前它需要所有行,将它们分成 500 个块,然后使用异步线程设置同时发布它们。我有另一项工作,偶尔从服务器获取数据,我在想如果我返回服务器负载并将其存储在Config.ServerLoad 中,如果服务器受到重击,它可能会稍微隔开请求。这是我用来设置线程的代码:

var json = JsonConvert.SerializeObject(rowDto);
var threads = new Thread(new ParameterizedThreadStart(MultiThreadPostThead));
var thisThread = new PostParams() { postUrl = postUrl, json = json, callingThread = threads };
threads.Start(thisThread);
threads.IsBackground = true;
ThreadHandles.Add(thisThread);

我希望添加这样的内容:

thread.delay(Config.ServerLoad * 1000);

例如,如果服务器负载是 0.5,线程之间几乎没有延迟,但如果是 10,它会在帖子之间等待 10 秒。我看到了一些关于Task.Delay() 的信息,但没有看到任何线程。有没有什么我错过的东西可以帮助添加动态值延迟或设置最大并发线程数?

【问题讨论】:

标签: c# .net multithreading


【解决方案1】:

如果你想延迟新线程的启动,那么你可以做一些事情

PerformanceCounter cpuCounter;
cpuCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");

var thisThread = new PostParams() { postUrl = postUrl, json = json, callingThread = threads };
Thread.Sleep((int)(cpuCounter.NextValue() * 1000));
threads.Start(thisThread);

你可以做的另一件事是使用

threads.Sleep((int)(cpuCounter.NextValue() * 1000));

因为它是一个线程,所以应该有可用的方法

这应该获取当前的 Cpu 使用情况,然后在启动新线程之前让当前线程休眠一段时间 - 如果您已经在 Config 中存储了一个数字,那么您可以放弃执行上下文内容并将其替换为该值你有:)

【讨论】:

  • 谢谢,第二个选项是我最终做的,但如果我担心本地 CPU 负载,我真的很喜欢第一个选项。
【解决方案2】:

我自己通常不使用线程,但更喜欢你提到的任务。

.Net 有一个非常直接的异步设计模式;通过声明您的方法 async 您定义该方法始终应该在异步上下文中调用。如果您选择使用以下示例,您将不再需要等待一定的时间,而是在完成任务后继续异步执行。

    public class MyResult {
        public string Result;
    }

    public async void Program() {

        var Timeout = 1000;
        Task<MyResult> Assignment = GetResult();

        // two ways of getting output:
        // 1: We wait using the task library
        Task.WaitAll(new Task[] { Assignment }, Timeout);
        MyResult r1 = Assignment.Result;

        // 2: We wait using the async methods:
        MyResult r2 = await Assignment;
    }

    public async Task<MyResult> GetResult() {
        // You can find methods which by default is async, therefore not needing to start the task yourself.
        return await Task.Factory.StartNew(() => LoadFromDatabase());
    }

    private MyResult LoadFromDatabase() {
        // Just testing.
        return new Question1.StartingTasks.MyResult() { Result = "TestResult" };
    }

如果您不熟悉异步方法,我建议您使用一些简单的类,例如这个示例,来了解这些方法的行为。

--- 额外

如果您使用 Task.Delay(Time) 没有成功,您必须记住等待任务完成,例如Task.WaitAll(Task.Delay(500));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    相关资源
    最近更新 更多