Hej ! :)
Mam do wykonania 3 rzeczy:
- Wczytać stream,
- Określić amplitudy dźwięków i zapisać je w liście,
- Narysować widmo dźwięku w Canvasie w oparciu o tą listę
Z racji tego, że są to czasochłonne procesy użyłem do tego csharp await.Task.Run()
Przy zmianie rozmiaru Canvasa owy obraz powienien się odrysować na nowo, co wiąże się z wywołaniem kolejnego zadania. Stanąłem przed wyzwaniem sprawdzenia, czy obraz się w danym momencie nie rysuje i zatrzymać go, a następnie zacząć tworzenie obrazu z nowymi rozmiarami. Postanowiłem użyć do tegocsharp CancellationToken
.
Wygląda to mniejwięcej tak:
private async Task DetectWaveformAsync(int Length)
{
try
{
if (DetectWaveFormCancellationToken != null)
DetectWaveFormCancellationToken.Cancel();
DetectWaveFormCancellationToken = new CancellationTokenSource();
await Task.Run(() => {
MaxLvl = 0;
UpperList.Clear();
LowerList.Clear();
// Fill Double List
for (int i = 0; i < Length; i += 1)
{
// Get left and right levels.
float[] levels = new float[2];
Bass.BASS_ChannelGetLevel(Stream, levels);
float leftLevel = levels[0];
float rightLevel = levels[1];
// Set MaxLvl
if (leftLevel > MaxLvl)
MaxLvl = leftLevel;
if (rightLevel > MaxLvl)
MaxLvl = rightLevel;
//Fill List
UpperList.Add(leftLevel);
LowerList.Add(rightLevel);
ProgressPercentage = HowManyPercent(i, Length);
DetectWaveFormCancellationToken.Dispose();
DetectWaveFormCancellationToken = null;
}
DetectWaveSucces();
},
DetectWaveFormCancellationToken.Token
);
}
catch (OperationCanceledException)
{
DetectWaveAborted();
DetectWaveFormCancellationToken.Dispose();
DetectWaveFormCancellationToken = null;
}
catch (Exception)
{
}
}
private CancellationTokenSource DetectWaveFormCancellationToken = null;
Zastanawiam się, czy samo wywołanie:
if (DetectWaveFormCancellationToken != null)
{
DetectWaveFormCancellationToken.Cancel();
DetectWaveFormCancellationToken.Dispose()
}
wystarczy, aby wymusić wywołanie ```csharp
catch (OperationCanceledException)