Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 代码可以工作,但似乎是同步运行的,而不是异步运行的 static void Main(字符串[]args) { //对列表中的每个股票执行异步方法 任务符号=Helper.getStockSymbols(“美国运通”,0); 列表任务=新列表(); 尝试 { 对于(int i=0;igetThreadStatus(任务)); } } //除非他们选择退出,否则不要退出 while(args.FirstOrDefault()!=“退出”) { //无所事事 } } 捕获(例外情况除外) { 控制台写入线(例如消息); } } 公共静态无效getThreadStatus(列表任务列表) { 整数计数=0; foreach(任务列表中的任务t) { if(t.Status==TaskStatus.Running) { 计数+=1; } } WriteLine(计数+“线程正在运行”); } 公共静态异步任务getCalculationsDataAsync(字符串符号,字符串市场) { //在这里做计算 }_C#_Multithreading_Asynchronous - Fatal编程技术网

C# 代码可以工作,但似乎是同步运行的,而不是异步运行的 static void Main(字符串[]args) { //对列表中的每个股票执行异步方法 任务符号=Helper.getStockSymbols(“美国运通”,0); 列表任务=新列表(); 尝试 { 对于(int i=0;igetThreadStatus(任务)); } } //除非他们选择退出,否则不要退出 while(args.FirstOrDefault()!=“退出”) { //无所事事 } } 捕获(例外情况除外) { 控制台写入线(例如消息); } } 公共静态无效getThreadStatus(列表任务列表) { 整数计数=0; foreach(任务列表中的任务t) { if(t.Status==TaskStatus.Running) { 计数+=1; } } WriteLine(计数+“线程正在运行”); } 公共静态异步任务getCalculationsDataAsync(字符串符号,字符串市场) { //在这里做计算 }

C# 代码可以工作,但似乎是同步运行的,而不是异步运行的 static void Main(字符串[]args) { //对列表中的每个股票执行异步方法 任务符号=Helper.getStockSymbols(“美国运通”,0); 列表任务=新列表(); 尝试 { 对于(int i=0;igetThreadStatus(任务)); } } //除非他们选择退出,否则不要退出 while(args.FirstOrDefault()!=“退出”) { //无所事事 } } 捕获(例外情况除外) { 控制台写入线(例如消息); } } 公共静态无效getThreadStatus(列表任务列表) { 整数计数=0; foreach(任务列表中的任务t) { if(t.Status==TaskStatus.Running) { 计数+=1; } } WriteLine(计数+“线程正在运行”); } 公共静态异步任务getCalculationsDataAsync(字符串符号,字符串市场) { //在这里做计算 },c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,我试图在代码中为列表中的每个股票运行一个新任务,并同时运行它们。我有一个4核处理器,我相信这意味着我一次只能运行4个任务。我尝试通过插入continuewith方法来测试有多少任务正在运行,您可以在我的代码中看到该方法,该方法将告诉我有多少任务正在运行。当我运行此代码时,它告诉我0个任务正在运行,因此我的问题是: 如何通过同时执行这些任务来完成目标 为什么它告诉我0个任务正在运行?我只能假设这是因为当前任务已经完成,如果任务一个接一个地运行,它还没有启动新任务 我不知道你为什么没有看到任务在运行

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

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

  • 我不知道你为什么没有看到任务在运行。你确定你的
    任务.Run()
    被击中了吗?也就是说,
    i
    满足了吗

    不管上述情况如何,让我们努力实现您的目标。首先,不,因为您的机器有四个物理内核/线程,所以您最多可以使用四个
    Thread
    s是不正确的。这些是不同的事情。关于这个主题的谷歌会给你带来大量的信息

    基本上,以您所拥有的方式启动线程将在线程池上启动后台线程,该线程池可以容纳/管理大量线程。有关更多信息,请参阅。无论何时启动线程,都要花费几百微秒来组织新的私有局部变量堆栈之类的事情。每个线程还消耗(默认情况下)大约1MB的内存。线程池通过共享和循环线程来减少这些开销,从而允许以非常精细的级别应用多线程,而不会造成性能损失。这在利用多核处理器以“分而治之”方式并行执行计算密集型代码时非常有用

    线程池还限制了它将同时运行的工作线程的总数。太多的活动线程会限制操作系统的管理负担,并使CPU缓存无效。一旦达到某个限制,作业将排队,只有在另一个作业完成时才开始

    好的,现在看你的代码。假设我们有一个股票类型列表

    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
    }
    
    这将触发三个后台线程池线程,并且是非阻塞的,因此此代码将几乎立即返回到调用方

    如果要设置后期处理,可以通过延续和延续链接来实现。以上我提供的Albahari链接中描述了所有这些

    我希望这有帮助

    --

    编辑。回应评论:

    从.NET Framework版本4开始,进程线程池的默认大小取决于多个因素,例如虚拟地址空间的大小。进程可以调用GetMaxThreads方法来确定线程数

    然而,还有其他一些因素在起作用:线程池不会在所有情况下立即创建新线程。为了应对突发的小任务,它限制了创建新线程的速度。IIRC,如果有未完成的任务,它将每0.5秒创建一个线程,最大线程数。不过,我无法立即看到记录的数字,因此很可能会发生变化。我强烈怀疑这就是你所看到的。尝试将大量项目排队,然后随时间监视线程数


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

    我认为问题在于任务的状态是
    正在运行
    ,或者非常短暂,或者可以跳过该状态,直接从
    等待激活
    转到
    RanToCompletion

    我稍微修改了您的程序,我可以看到任务开始和完成,但每当我检查时,它们似乎不处于运行状态

    foreach (string t in types)
    {
        Task.Factory.StartNew(() => DoSomeCalculationForType(t));
    }
    
    正如我在博客上描述的那样。只有委托任务实际运行过。承诺只完成任务。
    task.Run返回的任务是承诺任务,不是委托任务;并且仅当
    async
    代码完成时才完成

    因此,检查
    TaskStatus.Running
    不会按您想要的方式工作。相反,您可以创建一个计数器:

    Starting task
    Delay:1784
    Starting task
    Delay:2906
    Starting task
    Delay:2906
    Starting task
    Delay:2906
    Starting task
    Delay:2906
    Tasks Count:5
    Finished task
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Finished task
    Finished task
    Finished task
    Status RanToCompletion
    Status RanToCompletion
    Status WaitingForActivation
    Status WaitingForActivation
    Status RanToCompletion
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Finished task
    Status RanToCompletion
    Status RanToCompletion
    Status RanToCompletion
    Status RanToCompletion
    Status WaitingForActivation
    
    private static int\u count;
    静态void Main(字符串[]参数)
    {
    ...
    对于(int i=0;igetCalculationsDataWithCountAsync(符号“amex”);
    任务。添加(t);
    }
    }
    
    static void Main(string[] args)
    {
        // do async method for each stock in the list
        Task<IEnumerable<string>> symbols = Task.FromResult(Enumerable.Range(1, 5).Select (e => e.ToString()));
    
        List<Task> tasks = new List<Task>();
    
        try
        {
            for (int i = 0; i < symbols.Result.Count(); i++)
            {
                 string symbol = symbols.Result.ElementAtOrDefault(i);
                 Task t = getCalculationsDataAsync(symbol, "amex", tasks);
                 tasks.Add(t);           
            }               
    
            Console.WriteLine("Tasks Count:"+ tasks.Count());                       
            Task.WaitAll(tasks.ToArray());
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    
    public static void getThreadStatus(List<Task> taskList)
    {
        int count = 0;
    
        foreach (Task t in taskList)
        {
            Console.WriteLine("Status " + t.Status);
            if (t.Status == TaskStatus.Running)
            {
                count += 1;
                Console.WriteLine("A task is running");
            }
        }
    
        //Console.WriteLine(count + " threads are running.");
    }
    
    public static async Task getCalculationsDataAsync(string symbol, string market, List<Task> tasks)
    {
        Console.WriteLine("Starting task");
        var delay = new Random((int)DateTime.Now.Ticks).Next(5000);
        Console.WriteLine("Delay:" + delay);
        await Task.Delay(delay);
        Console.WriteLine("Finished task");
        getThreadStatus(tasks);
    }
    
    Starting task
    Delay:1784
    Starting task
    Delay:2906
    Starting task
    Delay:2906
    Starting task
    Delay:2906
    Starting task
    Delay:2906
    Tasks Count:5
    Finished task
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Finished task
    Finished task
    Finished task
    Status RanToCompletion
    Status RanToCompletion
    Status WaitingForActivation
    Status WaitingForActivation
    Status RanToCompletion
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Status WaitingForActivation
    Finished task
    Status RanToCompletion
    Status RanToCompletion
    Status RanToCompletion
    Status RanToCompletion
    Status WaitingForActivation
    
    private static int _count;
    static void Main(string[] args)
    {
      ...
        for (int i = 0; i < symbols.Result.Count(); i++)
        {
          if (i < symbols.Result.Count())
          {
            string symbol = symbols.Result.ElementAtOrDefault(i);
            Task t = Task.Run(() => getCalculationsDataWithCountAsync(symbol, "amex"));
            tasks.Add(t);
          }
        }
      ...
    }
    
    public static async Task getCalculationsDataWithCountAsync(string symbol, string market)
    {
      Console.WriteLine(Interlocked.Increment(ref _count) + " threads are running.");
      try
      {
        await getCalculationsDataAsync(symbol, market);
      }
      finally
      {
        Console.WriteLine(Interlocked.Decrement(ref _count) + " threads are running.");
      }
    }