Ошибка TLSharp при загрузке нескольких файлов - PullRequest
7 голосов
/ 24 февраля 2020

Я использую TLSharp. Моя цель - отправить файлы пользователю. Я создал ASP. NET Базовую службу веб-API и делаю HTTP-запрос, когда мне нужно отправить файл.

Он хорошо работает с одним файлом, но каждый раз, когда я получаю 2 или более запросов за короткий период времени я получаю ошибку:

System.InvalidOperationException: неверная контрольная сумма! skip.

Контроллер :

[Route("upload/{driveId}")]
public async Task<ActionResult> Upload(string driveId)
{
    var ms = new MemoryStream();
    var file = service.Files.Get(driveId);
    string filename = file.Execute().Name;
    await file.DownloadAsync(ms);
    ms.Position = 0;
    new FileExtensionContentTypeProvider().TryGetContentType(filename, out var mime);

    var stream = new StreamReader(ms, true);
    await _client.SendFileToBot(filename, mime, stream, driveId);

    return Ok();
}

Метод SendFileToBot :

public async Task SendFileToBot(string filename, string mime, StreamReader stream)
{
    var found = await client.SearchUserAsync("username", 1);

    //find user
    var userToSend = found.Users
        .Where(x => x.GetType() == typeof(TLUser))
        .Cast<TLUser>()
        .FirstOrDefault(x => x.Id == 1234567);

    var fileResult = await client.UploadFile(filename, stream);
    var attr = new TLVector<TLAbsDocumentAttribute>()
    {
        new TLDocumentAttributeFilename { FileName = filename }
    };
    var bot = new TLInputPeerUser() { UserId = userToSend.Id, AccessHash = userToSend.AccessHash.Value };
    await client.SendUploadedDocument(bot, fileResult, "caption", mime, attr);
}

Когда запросы отправленные вместе (или за короткий промежуток времени), они отправляются в одном пакете на сервер Telegram, и возникает эта ошибка. Мне нужна помощь с этой ошибкой. Я пытался использовать Task.Delay, но это не помогло.

Как мне обрабатывать запросы, чтобы избежать этой ошибки?

1 Ответ

0 голосов
/ 03 марта 2020

Согласно этой проблеме, вы не первый, кто получил эту ошибку.

Похоже, что при использовании многопоточности в библиотеке TLSharp возникли проблемы с запросом / ответом.

Существует один стабильный обходной путь для таких проблем.

Сделайте все запросы на загрузку синхронными

На самом деле они будут асинхронными, но с одной задачей в одном. время доступа

Это грязное, но выполнимое решение может быть достигнуто путем создания очереди задач :

public class TaskQueue
{
    private readonly SemaphoreSlim _semaphoreSlim;

    public TaskQueue()
    {
        _semaphoreSlim = new SemaphoreSlim(1, 1); // Max threads limited to 1.
    }

    public async Task<T> Enqueue<T>(Func<Task<T>> taskGenerator)
    {
        await _semaphoreSlim.WaitAsync();

        try
        {
            return await taskGenerator();
        }
        finally
        {
            _semaphoreSlim.Release();
        }
    }

    public async Task Enqueue(Func<Task> taskGenerator)
    {
        await _semaphoreSlim.WaitAsync();
        try
        {
            await taskGenerator();
        }
        finally
        {
            _semaphoreSlim.Release();
        }
    }
}

Теперь вы должны зарегистрировать очередь как singleton в Startup.cs файле, чтобы убедиться, что ваше основное приложение asp. net использует одну очередь задач экземпляр для выполнения загрузки на серверы телеграммы:

public void ConfigureServices(IServiceCollection services)
{
    //...
    services.AddSingleton<TaskQueue>();
    //...
}

Далее, получите свой экземпляр очереди задач в конструкторе вашего контроллера API, например:

private readonly TaskQueue taskQueue;

public MyController(TaskQueue taskQueue)
{
    this.taskQueue = taskQueue
}

Затем просто используйте его во всех ваших методах API:

// Code from your API method...
await taskQueue.Enqueue(() => client.SendUploadedDocument(bot, fileResult, "caption", mime, attr));

Это сделает все запросы к серверам телеграмм. через TLSharp librar y синхронны и предотвращают проблемы многопоточности, как в вопросе.


Если честно, это всего лишь обходной путь , а не решение этой проблемы. Я уверен, что эта проблема на github об ошибке контрольной суммы должна быть исследована более подробно и исправлена, если это возможно.

...