C# 代码获取一个对象的属性偶尔就卡死了 srting retmess = card.RetMsg;  是偶发的不是每次都卡死
卡死原因不明, 
我尝试新写一个线程和一个方法取赋值如下 
线程:
                Thread thread1 = new Thread(new ThreadStart(getMess)); 
                thread1.IsBackground = true; 
                thread1.Start();
方法:
        public static void getMess()
        { 
            retmess = card.RetMsg;    //这代码卡死
        } 
执行之后偶尔也会卡死  ,在卡死之后我尝试执行 thread1.Abort()也会卡死, 这个线程关不掉,有没有办法关掉线程 
card对象是别人的框架里面的一个对象的实例,

解决方案 »

  1.   

    1.如果只能用Thread,
    那么多线程访问的公用变量或者对象,需要加锁
    调用相关函数出现阻塞,得查阻塞的原因2.如果是c# 4.0之后的版本,
    推荐使用Task,这样可以实现带超时机制的异步处理
      

  2.   

    你先不要用线程访问这个属性。用主线程访问试试。如果没问题,可能是这个属性定义的有问题,是非线程安全的。它内部实现可能是跨了线程,可能是涉及到UI的修改,等各种不规范的行为。==========
    欢迎关注微信公众号 “产品技术知与行” ,打造全面的结构化知识库,包括原创文章、免费课程(C#,Java,Js)、技术专题、视野知识、源码下载等内容。 
    最新文章:解读经典《C#高级编程》 第四章之 泛型的原理 https://mp.weixin.qq.com/s/3264VdbzqXWt7vn19ARrPQ
      

  3.   


    using System.Linq;
    using System.Threading;namespace ConsoleApp1
    {
        class Program
        {
            static void Main(string[] args)
            {
                int tasktime = 5000;
                int timeout = 3000;            EventWaitHandle handle = new ManualResetEvent(false);            System.Threading.Tasks.Task.Run(() =>
                {
                    Thread.Sleep(tasktime);
                    handle.Set();
                });            var action = WaitHandle.WaitAny(new WaitHandle[] { handle }, TimeSpan.FromMilliseconds(timeout));            if (action == WaitHandle.WaitTimeout)
                {
                    Console.WriteLine("超时执行任务");
                }
                else {
                    Console.WriteLine("正常完成任务");
                }            Console.ReadKey();
            }
        }
    }
    修改
                int tasktime = 5000;
                int timeout = 3000;
    的值,看看执行结果有什么变化,想想为什么和怎么处理超时的Task。我觉得自己可以去做老师…………
      

  4.   

    你有一句话说的才是正确的“越点越多”,说明什么?说明你不是等待完成,而是重新添加再从card.RetMsg来看,应该是读卡操作。这类东西通常是唯一资源,(tcp固定套接字,串口),操作这类东西时候,本身会有一个等待连接的过程,当你不停加入新线程的时候,其实就在不停尝试连接过程所以,解决方法是
    1.lock他
    2.超时释放他
      

  5.   

    建议你采用下面步骤定位问题:
    1.你可以自己定义一个对象替代card,启动线程取值看看是否卡死。如果不会卡死,应该就是card有问题。
    2.启动两个线程,分别都调用【card.RetMsg;】,看看是否会卡死。如果会卡死,则是card锁有问题,或者说它不支持多线程处理。
      

  6.   


    现在的问题是 lz 自以为人家的驱动支持多线程调用。这就跟自以为“不能支持多线程调用”一样,都是不可靠的猜测。我只是回答下楼主说的“不结束的话 我多次调用,线程会越来越多”问题,
    说明每次调用,楼主都会新建一个线程来处理。但本身是没必要的,
    第一是每个线程的处理时间不确定,
    第二无法确定多次调用,这个多次是多少次,
    本质上这样的处理一个线程来处理是完全够用的,还能避免一些其他的问题(比如你说的是否支持多线程的问题)。string g_sOldValue = card.RetMsg;
    where (true)
    {
    string sNewValue = card.RetMsg;
    if (sNewValue != g_sOldValue)
    {
    func();
    g_sOldValue = sNewValue;
    }

    sleep(1);
    }
      

  7.   

    设一个超时时间,task同时执行取值和计时,超过时间没用成功赋值,销毁task,试试