加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 代码工作但似乎同步运行而不是异步

发布时间:2020-12-15 22:03:45 所属栏目:百科 来源:网络整理
导读:static void Main(string[] args){ // do async method for each stock in the list TaskIEnumerablestring symbols = Helper.getStockSymbols("amex",0); ListTask tasks = new ListTask(); try { for (int i = 0; i symbols.Result.Count(); i++) { if (i
static void Main(string[] args)
{
    // do async method for each stock in the list
    Task<IEnumerable<string>> symbols = Helper.getStockSymbols("amex",0);
    List<Task> tasks = new List<Task>();

    try
    {
        for (int i = 0; i < symbols.Result.Count(); i++)
        {
            if (i < symbols.Result.Count())
            {
                string symbol = symbols.Result.ElementAtOrDefault(i);
                Task t = Task.Run(() => getCalculationsDataAsync(symbol,"amex"));
                tasks.Add(t);
                Task e = t.ContinueWith((d) => getThreadStatus(tasks));
            }
        }

        // don't exit until they choose to
        while (args.FirstOrDefault() != "exit")
        {
            // do nothing

        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

public static void getThreadStatus(List<Task> taskList)
{
    int count = 0;

    foreach (Task t in taskList)
    {
        if (t.Status == TaskStatus.Running)
        {
            count += 1;
        }
    }

    Console.WriteLine(count + " threads are running.");
}

public static async Task getCalculationsDataAsync(string symbol,string market)
{
    // do calculation here
}

我在我的代码中尝试做的是为列表中的每个库存运行一个新任务,并同时运行它们.我有一个4核处理器,我相信这意味着我一次只能运行4个任务.我尝试通过插入您在我的代码中看到的continuewith方法来测试运行的任务数量,该方法将告诉我正在运行的任务数量.当我运行此代码时,它告诉我0个任务正在运行,所以我的问题是:

>如何通过在同一时间运行这些任务来完成我的目标?
>为什么告诉我0个任务正在运行?我只能假设这是因为当前任务已经完成,如果任务一个接一个地运行,它还没有启动新任务.

解决方法

我不确定你为什么看不到任何任务在运行.你确定你的Task.Run()被击中了吗?也就是说我是< symbols.Result.Count()满意吗? 无论如何,让我们尝试实现您想要的.首先,不,这是不正确的,因为你的机器有四个物理核心/’线程’,你可以使用最多四个线程.这些都不是一回事.关于此主题的谷歌将以如此方式提供大量信息. 基本上以您的方式启动线程将在线程池上启动后台线程,并且此线程池可以保存/管理多个线程,请参阅 Threading in C# by J. Albahari以获取更多信息.每当你启动一个线程时,花费几百微秒来组织一些新的私有局部变量栈.每个线程也消耗(默认情况下)大约1 MB的内存.线程池通过共享和回收线程来减少这些开销,允许在非常精细的级别上应用多线程而不会降低性能.当利用多核处理器以“分而治之”的方式并行执行计算密集型代码时,这非常有用.

线程池还会限制它将同时运行的工作线程总数.过多的活动线程会对管理负担限制操作系统,并使CPU缓存无效.达到限制后,作业将排队并仅在另一个完成时启动.

好的,现在为您的代码.我们假设我们有一个库存类型列表

List<string> types = new List<string>() { "AMEX","AMEC","BP" };

要为每个线程调度多个线程(不使用async / await),你可以做类似的事情

foreach (string t in types)
{
    Task.Factory.StartNew(() => DoSomeCalculationForType(t));
}

这将激活三个后台线程池线程并且是非阻塞的,因此这段代码几乎会立即返回给调用者.

如果要设置后期处理,可以通过continuation和continuation chaining来完成.这在我上面提供的Albahari链接中有所描述.

我希望这有帮助.

编辑.发表评论:

Beginning with the .NET Framework version 4,the default size of the thread pool for a process depends on several factors,such as the size of the virtual address space. A process can call the GetMaxThreads method to determine the number of threads.

但是,还有其他的东西在起作用:线程池不会立即在所有情况下创建新线程.为了应对小任务的爆发,它限制了创建新线程的速度. IIRC,如果有未完成的任务,它将每0.5秒创建一个线程,直到最大线程数.我不能立即看到这个数字,但它可能会改变.我强烈怀疑这是你所看到的.尝试排队很多项目,然后监视一段时间内的线程数.

基本上让线程池调度它想要的东西,它的优化器将为你的环境做最好的工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读