1. 程式人生 > 實用技巧 >使用TLSharp進行Telegram中遭遇迴圈體內報session.dat檔案被佔用時解決方式一例

使用TLSharp進行Telegram中遭遇迴圈體內報session.dat檔案被佔用時解決方式一例

背景

公司做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(;