C # - вызвать событие с данными из задачи - PullRequest
0 голосов
/ 28 октября 2019

Я пытаюсь создать класс, который загружает URL-адрес и сообщает о его прогрессе, вызывая событие при загрузке блока байтов. Я могу изменить свойства и использовать INotifyPropertyChanged, и он работает нормально. Однако, если я пытаюсь вызвать событие из задачи, задача останавливается, и больше ничего не происходит.

Япытаясь понять, что происходит.

Класс:

public class DownloadItem : INotifyPropertyChanged
{
    private HttpClient httpClient;   

    public string URL { get; private set; }
    public string LocalPath { get; private set; }
    public long BytesReceived { get; private set; }
    public long BytesTotal { get; private set; }    

    ...

    public void Start()
    {
        Task.Run(async () =>
        {
            HttpResponseMessage response = await httpClient.GetAsync(this.URL, HttpCompletionOption.ResponseHeadersRead);

            this.BytesTotal = (long)response.Content.Headers.ContentLength;

            using (var fsDest = new FileStream(this.LocalPath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                using (var sourceStream = await response.Content.ReadAsStreamAsync())
                {
                    byte[] buffer = new byte[2048];
                    int bytesRead;
                    var e = new DownloadProgressChangedEventArgs();

                    while ((bytesRead = sourceStream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        fsDest.Write(buffer, 0, bytesRead);

                        this.BytesReceived += bytesRead;

                        /* NOT WORKING! */
                        e.BytesReceived = this.BytesReceived;
                        e.BytesTotal = this.BytesTotal;
                        OnDownloadProgressChange(e);
                    }
                }
            }

            httpClient.Dispose();
        });
    }

    public class DownloadProgressChangedEventArgs : EventArgs
    {
        public long BytesReceived { get; set; }
        public long BytesTotal { get; set; }
    }
    public event EventHandler<DownloadProgressChangedEventArgs> DownloadProgressChanged;
    protected virtual void OnDownloadProgressChange(DownloadProgressChangedEventArgs e)
    {
        DownloadProgressChanged?.Invoke(this, e);
    }
}

Попытка использовать его в приложении WinForms:

DownloadItem c;
public Form1()
{
    ...
    c.DownloadProgressChanged += c_DownloadProgressChanged;
}
private void c_DownloadProgressChanged(object sender, DownloadItem.DownloadProgressChangedEventArgs e)
{
    label1.Text = e.BytesReceived + "  " + e.BytesTotal;
}

Любая помощь будет принята с благодарностью.

...