を呼び出すとStop()
、OperationCanceledException
発生し、_writer.TryComplete(exp)
真になります。しかし_reader.Completion
Task
、まだ完成していません。
チャネルの望ましい動作ですか? はいの場合、誰かがChannel
空になるまで待たずに停止Completion
Task
してCompleted
状態にする方法を教えてもらえますか?
public interface IItem
{
Uri SourceUri { get; }
string TargetPath { get; }
}
public class Item : IItem
{
public Item(Uri sourceUri, string targetPath)
{
SourceUri = sourceUri;
TargetPath = targetPath;
}
public Uri SourceUri { get; }
public string TargetPath { get; }
}
public class TestService
{
private readonly ChannelWriter<IItem> _writer;
private readonly ChannelReader<IItem> _reader;
private readonly CancellationTokenSource _cts;
public TestService()
{
_cts = new CancellationTokenSource();
Channel<IItem> channel = Channel.CreateUnbounded<IItem>();
_reader = channel.Reader;
_writer = channel.Writer;
}
public async Task QueueDownload(IItem information)
{
await _writer.WriteAsync(information);
}
public void StartDownload()
{
Task.Factory.StartNew(async () =>
{
await ProcessDownloadAsync();
}, TaskCreationOptions.LongRunning);
}
public void Stop()
{
_cts.Cancel();
//_writer.Complete();
//_writer = null;
Console.WriteLine("Stop");
}
public async Task Wait()
{
await _reader.Completion;
}
private async Task ProcessDownloadAsync()
{
try
{
while (await _reader.WaitToReadAsync(_cts.Token))
{
IItem information = await _reader.ReadAsync(_cts.Token);
using (WebClient webClient = new WebClient())
{
Console.WriteLine(information.TargetPath);
await webClient.DownloadFileTaskAsync(information.SourceUri,
information.TargetPath);
}
}
}
catch (OperationCanceledException exp)
{
bool res = _writer.TryComplete(exp);
}
}
}
static class Program
{
static async Task Main(string[] args)
{
TestService tSvc = new TestService();
await tSvc.QueueDownload(new Item(new Uri(@"https://images.pexels.com/" +
@"photos/753626/pexels-photo-753626.jpeg"), @"D:\\Temp\1.png"));
await tSvc.QueueDownload(new Item(new Uri(@"https://images.pexels.com/" +
@"photos/753626/pexels-photo-753626.jpeg"), @"D:\\Temp\1.png"));
await tSvc.QueueDownload(new Item(new Uri(@"https://images.pexels.com/" +
@"photos/753626/pexels-photo-753626.jpeg"), @"D:\\Temp\1.png"));
await tSvc.QueueDownload(new Item(new Uri(@"https://images.pexels.com/" +
@"photos/753626/pexels-photo-753626.jpeg"), @"D:\\Temp\1.png"));
tSvc.StartDownload();
Task t = tSvc.Wait();
tSvc.Stop();
await t;
Console.WriteLine("Finished");
}
}