Last active
July 11, 2021 11:46
-
-
Save habibg1232191/38221856060192b636db69b13872746b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Unhandled exception. System.InvalidOperationException: Collection was modified; enumeration operation may not execute. | |
at System.Collections.Generic.List`1.Enumerator.MoveNextRare() | |
at Avalonia.Controls.Presenters.ItemContainerSync.AddContainers(ItemsPresenterBase owner, Int32 index, IEnumerable items) in /_/src/Avalonia.Controls/Present | |
ers/ItemContainerSync.cs:line 89 | |
at Avalonia.Controls.Presenters.ItemContainerSync.ItemsChanged(ItemsPresenterBase owner, IEnumerable items, NotifyCollectionChangedEventArgs e) in /_/src/Ava | |
lonia.Controls/Presenters/ItemContainerSync.cs:line 73 | |
at Avalonia.Controls.Presenters.ItemVirtualizerNone.ItemsChanged(IEnumerable items, NotifyCollectionChangedEventArgs e) in /_/src/Avalonia.Controls/Presenter | |
s/ItemVirtualizerNone.cs:line 59 | |
at Avalonia.Controls.Presenters.ItemsPresenterBase.set_Items(IEnumerable value) in /_/src/Avalonia.Controls/Presenters/ItemsPresenterBase.cs:line 72 | |
at Avalonia.Controls.ItemsControl.ItemsChanged(AvaloniaPropertyChangedEventArgs e) in /_/src/Avalonia.Controls/ItemsControl.cs:line 356 | |
at Avalonia.Controls.ItemsControl.<>c.<.cctor>b__8_0(ItemsControl x, AvaloniaPropertyChangedEventArgs e) in /_/src/Avalonia.Controls/ItemsControl.cs:line 64 | |
at System.Reactive.Subjects.Subject`1.OnNext(T value) in /_/Rx.NET/Source/src/System.Reactive/Subjects/Subject.cs:line 145 | |
at Avalonia.AvaloniaObject.RaisePropertyChanged[T](AvaloniaPropertyChangedEventArgs`1 change) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 758 | |
at Avalonia.AvaloniaObject.SetAndRaise[T](AvaloniaProperty`1 property, T& field, T value) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 705 | |
at Avalonia.Controls.ItemsControl.set_Items(IEnumerable value) in /_/src/Avalonia.Controls/ItemsControl.cs:line 108 | |
at Avalonia.Controls.ItemsControl.<>c.<.cctor>b__8_4(ItemsControl o, IEnumerable v) in /_/src/Avalonia.Controls/ItemsControl.cs:line 35 | |
at Avalonia.AvaloniaObject.SetDirectValueUnchecked[T](DirectPropertyBase`1 property, BindingValue`1 value) in /_/src/Avalonia.Base/AvaloniaObject.cs:line 822 | |
at Avalonia.AvaloniaObject.DirectBindingSubscription`1.<>c__DisplayClass7_0.<OnNext>b__0() in /_/src/Avalonia.Base/AvaloniaObject.cs:line 941 | |
at Avalonia.Threading.JobRunner.RunJobs(Nullable`1 priority) in /_/src/Avalonia.Base/Threading/JobRunner.cs:line 37 | |
at Avalonia.Win32.Win32Platform.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam) in /_/src/Windows/Avalonia.Win32/Win32Platform.cs:line 210 | |
at Avalonia.Win32.Interop.UnmanagedMethods.DispatchMessage(MSG& lpmsg) | |
at Avalonia.Win32.Win32Platform.RunLoop(CancellationToken cancellationToken) in /_/src/Windows/Avalonia.Win32/Win32Platform.cs:line 157 | |
at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken) in /_/src/Avalonia.Base/Threading/Dispatcher.cs:line 61 | |
at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args) in /_/src/Avalonia.Controls/ApplicationLifetimes/Classi | |
cDesktopStyleApplicationLifetime.cs:line 116 | |
at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime[T](T builder, String[] args, ShutdownMode shutdownMode) in /_/sr | |
c/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 148 | |
at DownloadAnime.Program.Main(String[] args) in C:\Users\habib\RiderProjects\DownloadAnime\DownloadAnime\Program.cs:line 12 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Collections.ObjectModel; | |
using System.IO; | |
using System.Net; | |
using System.Threading; | |
using System.Threading.Tasks; | |
using Avalonia.Media.Imaging; | |
using Avalonia.Threading; | |
using DownloadAnime.Parser; | |
using DownloadAnime.Parser.ShikimoriModels; | |
using ReactiveUI; | |
namespace DownloadAnime.ViewModels | |
{ | |
public class HomePageViewModel : ViewModelBase | |
{ | |
public CancellationTokenSource Cts; | |
public CancellationToken Token; | |
private ObservableCollection<Animes> _adverts; | |
public ObservableCollection<Animes> Animes | |
{ | |
get => _adverts; | |
set | |
{ | |
if (_adverts != value) | |
{ | |
_adverts = value; | |
OnPropertyChanged(); | |
} | |
} | |
} | |
private string _searchText; | |
public string SearchText | |
{ | |
get => _searchText; | |
set | |
{ | |
if (_searchText != value) | |
{ | |
_searchText = value; | |
OnPropertyChanged(); | |
} | |
} | |
} | |
public HomePageViewModel() | |
{ | |
Cts = new CancellationTokenSource(); | |
Token = Cts.Token; | |
Animes = new ObservableCollection<Animes>(); | |
SearchText = ""; | |
this.WhenAnyValue(x => x.SearchText).Subscribe(SearchTextChanged); | |
} | |
private async void SearchTextChanged(string x) | |
{ | |
Cts.Cancel(); | |
Cts = new CancellationTokenSource(); | |
Token = Cts.Token; | |
if (x == "") | |
{ | |
await Dispatcher.UIThread.InvokeAsync(async () => | |
{ | |
await ShikimoriApiSend(Token); | |
}, DispatcherPriority.Input); | |
} | |
else | |
{ | |
Dictionary<string, string> parameters = new Dictionary<string, string>() | |
{ | |
{"search", x }, | |
{"limit", "50"} | |
}; | |
await Dispatcher.UIThread.InvokeAsync(async () => | |
{ | |
await ShikimoriApiSend(Token, parameters); | |
}, DispatcherPriority.Input); | |
} | |
} | |
public async Task ShikimoriApiSend(CancellationToken token, Dictionary<string, string>? parameters = null) | |
{ | |
if(token.IsCancellationRequested) | |
return; | |
await Task.Delay(10, token).ContinueWith(async task => | |
{ | |
await StartTask(token, parameters); | |
return false; | |
}, token); | |
} | |
public async Task StartTask(CancellationToken token, Dictionary<string, string>? parameters = null) | |
{ | |
if(token.IsCancellationRequested) | |
return; | |
var shikimoriApi = new ShikimoriApi(); | |
parameters ??= new Dictionary<string, string> | |
{ | |
{"limit", "50"}, | |
{"order", "popularity"} | |
}; | |
if(token.IsCancellationRequested) | |
return; | |
var animes = await shikimoriApi.GetAnimes(parameters); | |
ObservableCollection<Animes> save = new ObservableCollection<Animes>(); | |
if(token.IsCancellationRequested) | |
return; | |
lock (Animes) | |
{ | |
foreach (var anime in animes) | |
{ | |
if(token.IsCancellationRequested) | |
return; | |
var saveAnime = anime; | |
var imgDirStr = Directory.GetCurrentDirectory() + @"\cache\" + saveAnime.Id + ".jpg"; | |
try | |
{ | |
if (!File.Exists(imgDirStr)) | |
{ | |
var clientForDownloadImage = new WebClient(); | |
var address = "https://shikimori.one" + saveAnime.Image.Original.Split('?')[0]; | |
clientForDownloadImage.DownloadFile(address, imgDirStr); | |
} | |
saveAnime.Image!.BitmapOriginal = new Bitmap(imgDirStr); | |
} | |
catch (Exception _) | |
{ | |
return; | |
} | |
save.Add(saveAnime!); | |
if(token.IsCancellationRequested) | |
return; | |
Animes = save; | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment