c# - Mono/MonoTouch 下的 Task.Factory.StartNew() 延迟

标签 c# mono xamarin.ios

在 Mono 和 MonoTouch 下,我发现调用之间有大约 500 毫秒的延迟:

StartNew(Action<object> action, object state, CancellationToken cancellationToken, 
    TaskCreationOptions creationOptions, TaskScheduler scheduler);

以及工作程序代码实际开始执行的时间。

我创建了一个测试来展示这一点:

public static class TestTaskFactory
{
    private class TaskInfo
    {
        public int Number;
    }

    private static int NUM_TASKS = 5;
    private static int NumFinished = 0;

    public static void Run()
    {
        for (int n = 1; n <= NUM_TASKS; n++)
        {
            Log("Starting task #" + n + " ...");
            var task_info = new TaskInfo { Number = n };
            var task = Task.Factory.StartNew(Worker, task_info, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
            Thread.Sleep(0);
        }

        Log("Waiting for tasks to finish ...");
        while (NumFinished < NUM_TASKS)
        {
            Thread.Sleep(1);
        }

        Log("All done");
    }

    private static void Worker(object state)
    {
        var task_info = (TaskInfo)state;
        Log("Task #" + task_info.Number + " running");

        // Do something
        Thread.Sleep(2000);

        // Done
        ++NumFinished;
    }

    private static void Log(string msg)
    {
        Console.WriteLine(DateTime.Now.ToString("HH.mm.ss.fff") + ": Thread " + Thread.CurrentThread.ManagedThreadId + ": " + msg);
    }
}

Mac 上 Mono 下的输出:

16.57.31.420: Thread 1: Starting task #1 ...
16.57.31.508: Thread 1: Starting task #2 ...
16.57.31.508: Thread 1: Starting task #3 ...
16.57.31.508: Thread 1: Starting task #4 ...
16.57.31.508: Thread 1: Starting task #5 ...
16.57.31.508: Thread 1: Waiting for tasks to finish ...
16.57.31.510: Thread 5: Task #1 running
16.57.32.009: Thread 6: Task #2 running <-- Approx 500 msec later
16.57.32.511: Thread 7: Task #3 running <-- Approx 500 msec later
16.57.33.012: Thread 8: Task #4 running <-- Approx 500 msec later
16.57.33.513: Thread 9: Task #5 running <-- Approx 500 msec later
16.57.35.515: Thread 1: All done

就好像 Mono 想要等待最多 500 毫秒以在产生新线程之前重用现有线程。如果我将工作时间减少到 500 毫秒以下,延迟就会减少。例如,将 worker Thread.Sleep(2000) 更改为 Thread.Sleep(50):

...
17.13.20.262: Thread 5: Task #1 running
17.13.20.314: Thread 5: Task #2 running <-- approx 50 msec later
17.13.20.365: Thread 5: Task #3 running <-- approx 50 msec later
17.13.20.416: Thread 5: Task #4 running <-- approx 50 msec later
17.13.20.466: Thread 5: Task #5 running <-- approx 50 msec later

但是在 MS Framework 4.0 下,worker 代码启动前没有延迟:

...
17.05.42.238: Thread 9: Waiting for tasks to finish ...
17.05.42.256: Thread 11: Task #1 running
17.05.42.256: Thread 12: Task #3 running <-- little delay
17.05.42.256: Thread 13: Task #4 running <-- little delay
17.05.42.257: Thread 10: Task #2 running <-- little delay
17.05.43.264: Thread 14: Task #5 running <-- little delay

在我提交有关 Mono 的错误报告之前,我想检查一下我是否遗漏了一些我需要在 Mono 上进行的调整或错误地使用 Task.Factory。我实际上在我的真实应用程序中使用最大并发调度程序。

所以我的问题是:这是 Mono/MonoTouch 中的错误吗?

更新:我已经从使用 Mono* 下的 ThreadPool 切换到 Ami Bar 的智能线程池(githubCode Project article)。 GSerjo 的 Extended Thread Pool看起来也不错,但有很多我试图在移动设备上避免的依赖性。我在 Xamarim thread 上写了一些我的简单测试.我可能错过了 100 个其他线程池实现,但到目前为止我对 SmartThreadPool 很满意。 MonoTouch下使用WINDOWS_PHONE模式编译。

最佳答案

So my question: is this a bug in Mono/MonoTouch?

不一定。我怀疑这只是线程池不愿意每 500 毫秒启动一个以上的新线程。请注意,您看到第一个 任务几乎立即启动。只有在那之后,您才会看到延迟。

如果您在 .NET 4.5 上使用更多任务,您会看到类似的情况,除了每秒启动的线程“ block ”。

您可能会发现调用 ThreadPool.SetMinThreads有帮助,假设它在 MonoTouch 中可用。

关于c# - Mono/MonoTouch 下的 Task.Factory.StartNew() 延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13186371/

相关文章:

c# - 我创建了一个带有标题的母版页。在标题部分有一些链接..我想在不影响母版页的情况下突出显示这些链接

c# - 是否有一个预先存在的函数会根据基数和 "offset"返回一组数字?

c# - Mono 上的 WebSocket 证书(Mac,C#)

c# - MonoTouch.Dialog 中的图像或视频附件字段

xamarin.forms - OneSignal 通知扩展,错误找不到任何可用的配置文件

c# - 多线程:锁定属性 - 这是正确的吗?

c# - ASP.net Core 中的动态依赖注入(inject)

asp.net - 如何在 Linux 服务器上托管的 Mono 中部署 .NET Web 应用程序?

sqlite - Mono.Data.Sqlite.SqliteConnection 需要一个没有意义的 'System' 版本

c# - 带有下一页/上一页预览的 Xamarin iOS UIScrollView : Zoom Not Working as Expected