Answer the question
In order to leave comments, you need to log in
How to end a Task instantly?
Hello. Maybe someone will answer my question. In general, I'm developing an application, WPF, there are three IMAGE elements in the window. There is an animation flag. If the flag is off, then I output regular PNG files in Image.
There are also animations on the pictures, but not all. For example, 1 and 3 have animation, but 2 does not.
If the flag is on, then I output all the PNGs back, and then, using Task (since wpf does not support GIF, I display them in a separate thread through the redrawing of each frame), I start the animation. The whole point is that sometimes the flow remains, and when you select other pictures and animations, the frame of the previous animation freezes in the element.
The question is how to completely, and preferably, instantly, complete TASK and so that it does not hang in memory.
Here is the code of the Output itself
static CancellationTokenSource cancelTokenSource3 = new CancellationTokenSource();
CancellationToken token3 = cancelTokenSource3.Token;
public Task th_Image3;
volatile bool volatileComplette1 = false;
volatile bool volatileComplette2 = false;
volatile bool volatileComplette3 = false;
GifBitmapDecoder decoder3;
BitmapSource bitmapSource3;
int frameCount3;
th_Image3 = new Task(() =>
{
while (!volatileComplette3)
{
if (token3.IsCancellationRequested)
{
return;
}
for (int c = 0; ((c < frameCount3)&& (!volatileComplette3)); c++)
{
this.Dispatcher.Invoke(new Action(delegate ()
{
bitmapSource3 = decoder3.Frames[c];
Image_Right.Source = bitmapSource3;
if (token3.IsCancellationRequested)
{
return;
}
}));
System.Threading.Thread.Sleep(30);
if (token3.IsCancellationRequested)
{
return;
}
}
if (token3.IsCancellationRequested)
{
return;
}
}
}, token3);
th_Image3.Start();
Answer the question
In order to leave comments, you need to log in
Sorry for not answering your question - why don't you use https://github.com/XamlAnimatedGif/XamlAnimatedGif ?
In fact - if my memory serves me, there is no easy way to beat the Task, for this you need to use CancellationTokenSource, which is what you do in the above example. If cancellation via CancellationTokenSource does not work for some reason - set breakpoints or stick logs through each line, find a problematic place, and decide based on this information.
Based on your problem, to start after canceling, you can simply wait for the task to complete:
// Метод в котором останавливаете анимацию
cancellationTokenSource3.Cancel();
await th_Image3;
// Метод в котором останавливаете анимацию
cancellationTokenSource3.Cancel();
th_Image3.GetAwaiter().GetResult();
th_Image3 = Task.Run(() =>
{
// ......
});
// ......................
Semaphore _semaphore = new Semaphore(1, 1);
// ......................
th_Image3 = Task.Run(() =>
{
_semaphore.WaitOne();
try
{
// Показ GIF
}
finally
{
_semaphore.Release();
}
});
// .................................................
Task th_Image3 = Task.FromResult(0);
// .................................................
th_Image3 = th_Image3.ContinueWith(() =>
{
// Отображение GIF
});
And yet, about the animation, it should start and run until I press the button to the next animation, so the while is looped
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question