c# – 运行System.Threading.Tasks.Task时异常
请考虑以下使用CancellationTokenSource的基本任务库功能的代码.它启动一个线程,它填充一个字典的价格,并从SQL Server数据库读取数据.线程在大约10分钟后结束,每2个小时再次启动,首先调用Cancel,以防线程仍在运行.
private CancellationTokenSource mTokenSource = new CancellationTokenSource(); internal Prices(Dictionary<string,Dealer> dealers) { mDealers = dealers; mTask = Task.Factory.StartNew (() => ReadPrices(mTokenSource.Token),mTokenSource.Token); } internal void Cancel() { mTokenSource.Cancel(); } private void ReadPrices(CancellationToken ct) { using (SqlConnection connection = new SqlConnection(ConfigurationManager.AppSettings["DB"])) { connection.Open(); var dealerIds = from dealer in mDealers.Values where dealer.Id != null select dealer.Id; foreach (var dealerId in dealerIds) { if (!ct.IsCancellationRequested) { FillPrices(connection); } else break; } } } 在某些时候,应用程序在事件日志中遇到以下异常.
它必须与这里的代码有关,因为任务库不会在其他任何地方使用,但我不能弄清楚代码是什么问题.有人有什么想法吗? 解决方法
任务喜欢听的.这听起来好像不快乐.尽管如此,您可以获得“最后的机会”:
TaskScheduler.UnobservedTaskException += (sender,args) => { foreach (var ex in args.Exception.InnerExceptions) { Log(ex); } args.SetObserved(); }; 请注意,这不是解决方案 – 它的目的是让您看到任务正在爆炸以及出现什么错误. SetObserved()将阻止它杀死您的应用程序.但这里的解决方案是理想的: >不要让你的任务抛出, 您的取消检测可能不太满意. IIRC的首选方法是: foreach(...) { if(ct.IsCancellationRequested) { // any cleanup etc ct.ThrowIfCancellationRequested(); } ... } 或者更简单,如果不需要清理,只需: foreach(...) { ct.ThrowIfCancellationRequested(); ... } 同样地,它可能只是一个数据访问异常.在与数据库通信时可能会发生任何数量的异常.超时,死锁,无法连接等 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |