使用TLSharp進行Telegram中遭遇迴圈體內報session.dat檔案被佔用時解決方式一例
阿新 • • 發佈:2020-10-22
背景
公司做Telegram開發,.net Framework專案,呼叫TLSharp作為框架進行開發。
開發需求是讀取群裡新到達的資訊並進行過濾。
由此不可避免得要用到
TLSharp.Core.TelegramClient.GetHistoryAsync(TLAbsInputPeer peer, int offsetId = 0, int offsetDate = 0, int addOffset = 0, int limit = 100, int maxId = 0, int minId = 0, CancellationToken token = default);
這一方法。
由於每次都只能取得一個群的聊天曆史記錄,顯然地在讀取群列表之後第一想到地就是用linq
(await Listener.Client.SendRequestAsync<TLChats>(new TLRequestGetAllChats() { ExceptIds = new TeleSharp.TL.TLVector<int>() }) .ConfigureAwait(false)) .Chats .Where(item => item.GetType() == typeof(TLChannel)) .Cast<TLChannel>() .ToList() .ForEach(async item => { ((TLChannelMessages)await Listener.Client.GetHistoryAsync( peer: new TLInputPeerChannel() { ChannelId = item.Id, AccessHash = item.AccessHash.Value })) .Messages .Where(subitem => subitem.GetType() == typeof(TLMessage)) .Cast<TLMessage>() .Where(subitem => (subitem.Entities == null || (subitem.Entities != null && subitem.Entities.Count() < 5)) && !string.IsNullOrWhiteSpace(subitem.Message)) .ToList() .ForEach(subitem => { //實際處理訊息 }); });
但是很意外的,跑掛了!
報出的原因是session.dat檔案被佔用。
探索
session.dat檔案是TG的訊息會話檔案,受TLSharp管控,因此不能自主去管理檔案的開啟關閉和釋放。
於是抱著試一試的心理,把非同步去掉了,再跑起來,還是一樣的錯誤。
難道是Linq的問題?還是因為沒有加ConfigAwait(false)?
這個框架下試了幾次,均報session.dat被佔用。
於是用foreach改寫了這一段:
List<TLChannel> AllGroups = (await Listener.Client.SendRequestAsync<TLChats>(new TLRequestGetAllChats() { ExceptIds = new TeleSharp.TL.TLVector<int>() }) .ConfigureAwait(false)) .Chats .Where(item => item.GetType() == typeof(TLChannel)) .Cast<TLChannel>() .ToList(); foreach (TLChannel item in AllGroups) { ((TLChannelMessages)await Listener.Client.GetHistoryAsync( peer: new TLInputPeerChannel() { ChannelId = item.Id, AccessHash = item.AccessHash.Value })) .Messages .Where(subitem => subitem.GetType() == typeof(TLMessage)) .Cast<TLMessage>() .Where(subitem => (subitem.Entities == null || (subitem.Entities != null && subitem.Entities.Count() < 5)) && !string.IsNullOrWhiteSpace(subitem.Message)) .ToList() .ForEach(subitem => { //實際處理訊息 }); };
繼續跑,繼續掛!!
然後其實又把foreach改成了for(;