none
C#多线程控制台Console.WriteLine阻塞 RRS feed

  • 问题

  • 大家好,我在C#的控制台中创建了一个定时器用来检索数据库,并输出数据库内容的数量,当运行时间之后,我发现线程阻塞在了Console.WriteLine这里,必须手动输入一个按键才能继续执行,请问这是怎么回事?

                Console.WriteLine("服务开启.......");
                ChkPoolBuss chkPool = ChkPoolBuss.Instance;
                SearchBuss search = SearchBuss.Instance;
                search.AddListener(chkPool.OnchkdocChange);
                Thread thread = new Thread(search.Search);
                thread.Start();     
    using Lwcc.Extract.DAL;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace Lwcc.Extract.BLL.Bussiness
    {
        public class SearchBuss
        {
            private static readonly Lazy<SearchBuss> instance = new Lazy<SearchBuss>(() => new SearchBuss());
            private event ChkChange OnchkChange;
            public static SearchBuss Instance => instance.Value;
            public void Search()
            {
                while (true)
                {
                    SearchDocs();
                    Thread.Sleep(5000);
                }
            }
    
            private void SearchDocs()
            {
                using (ChkDB db = new ChkDB())
                {
                    var docs = db.ChkDocs.Where(item => item.State.Equals("11")).ToList();
                    if (docs.Count > 0)
                    {
                        docs.ForEach(item => item.State = "12");
                        db.SaveChanges();
                        OnchkChange?.Invoke(null, new ChkEventArgs() { CheckDocs = docs });
                    }
                    Console.Out.WriteLineAsync("---->当前需要检测的文档数量为--->"+docs.Count());
                }
            }
    
            public void AddListener(ChkChange chkChange)
            {
                OnchkChange += chkChange;
            }
    
        }
    }

    2018年11月20日 15:56

全部回复

  • 您好,您的示例代码不全,ChkPoolBuss,ChkChange没有代码。

    按照上面的示例,写了一个模拟代码,没啥问题,建议分析一下这行代码:

    OnchkChange?.Invoke(null, new ChkEventArgs() { CheckDocs = docs });

    测试代码:

     class SearchBuss
        {
            private static readonly Lazy<SearchBuss> instance = new Lazy<SearchBuss>(() => new SearchBuss());
            //private event ChkChange OnchkChange;
            public static SearchBuss Instance => instance.Value;
            public void Search()
            {
                while (true)
                {
                    SearchDocs();
                    Thread.Sleep(1000);
                }
            }
    
            private void SearchDocs()
            {
                Console.Out.WriteLineAsync("---->当前需要检测的文档数量为--->" + 100);
            }
        }
     class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("服务开启.......");
                
                SearchBuss search = SearchBuss.Instance;
               
                Thread thread = new Thread(search.Search);
                thread.Start();
            }
        }



    ericzhou

    2018年11月21日 1:26
  • 你好,感谢你的回复。据我查看资料,Console.WriteLine在高并发的状态下有可能造成控制台的假锁。因为我触发的事件,后面会使用parallel类进行并行操作,这些操作之后可能就造成了界面阻塞。后面我采取了Debug.WriteLine这个方法,测试了半天暂时没有发现问题。

    在微软的Console类参考手册中提示到:

            不要使用Console类,以在无人参与的应用程序,如服务器应用程序中显示输出。 调用方法如Console.WriteConsole.WriteLine GUI 应用程序中产生任何影响。

    2018年11月22日 11:28
  • Console类可以用,就看如何用了。

    ericzhou

    2018年11月23日 0:49