The problem described here does not exist, I was mistaken.
IInputStream.ReadAsync causes extraneous task

Sam of Simple Samples
5,546
Reputation points
When the clipboard has a Link Preview Format
as in Announcing a new way to paste URLs, Link format!, I am getting the contents in that format. After doing the GetDataAsync
the contents is an IRandomAccessStream
. Then I do a ReadAsync
. The first ReadAsync
seems to create a second task that begins with the GetDataAsync
and the two tasks continue in parallel. I posted my code below. The following shows the results I get, note that GetDataAsync
is executed twice.
New clipboard contents
Begin ImportEdgeLinkAsync
Begin Link Preview Format
After GetDataAsync
Before first read
After GetDataAsync
Before first read
After first read 206
Before subsequent read
After first read 206
Before subsequent read
After subsequent read 0
{"domain":"microsoft.com","preferred_format":"text/html;content=titled-hyperlink","title":"Ask a question - Microsoft Q&A","type":"website","url":"https://learn.microsoft.com/en-us/answers/questions/ask/"}
After subsequent read 0
{"domain":"microsoft.com","preferred_format":"text/html;content=titled-hyperlink","title":"Ask a question - Microsoft Q&A","type":"website","url":"https://learn.microsoft.com/en-us/answers/questions/ask/"}
using System.Text;
using System.Windows;
using Windows.ApplicationModel.DataTransfer;
using Windows.Storage.Streams;
namespace LinkPreview
{
public partial class MainWindow : Window
{
StringBuilder? diagnostics;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Windows.ApplicationModel.DataTransfer.Clipboard.ContentChanged += Clipboard_ContentChangedAsync;
}
private async void Clipboard_ContentChangedAsync(object? sender, object e)
{
DataPackageView dataPackageView = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
diagnostics = new StringBuilder("New clipboard contents\r\n");
if (dataPackageView.Contains("Link Preview Format"))
{
diagnostics!.AppendLine("Begin ImportEdgeLinkAsync");
await ImportEdgeLinkAsync(dataPackageView);
tb.Text = diagnostics.ToString();
return;
}
}
private async Task ImportEdgeLinkAsync(DataPackageView dataPackageView)
{
diagnostics!.AppendLine("Begin Link Preview Format");
object? obj;
try { obj = await dataPackageView.GetDataAsync("Link Preview Format"); }
catch (Exception ex)
{
tb.Text = $"GetDataAsync error: {ex.Message}";
return;
}
if (obj is not IRandomAccessStream ras)
{
tb.Text = "No stream";
return;
}
diagnostics!.AppendLine("After GetDataAsync");
StringBuilder stringbuffer;
try
{
stringbuffer = new();
Windows.Storage.Streams.Buffer buffer = new(1000);
diagnostics!.AppendLine("Before first read");
var operation = await ras.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.None);
diagnostics!.AppendLine($" After first read {operation.Length}");
while (operation.Length > 0)
{
using (var dataReader = DataReader.FromBuffer(buffer))
{
dataReader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
stringbuffer.Append(dataReader.ReadString(buffer.Length));
diagnostics!.AppendLine("Before subsequent read");
operation = await ras.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.None);
diagnostics!.AppendLine($" After subsequent read {operation.Length}");
}
}
}
catch (Exception ex)
{
diagnostics!.AppendLine($"InputStream error: {ex.Message}");
tb.Text = diagnostics!.ToString();
return;
}
diagnostics!.AppendLine(stringbuffer.ToString());
tb.Text = diagnostics!.ToString();
}
}
}
Developer technologies | Windows Presentation Foundation
2,860 questions
Developer technologies | C#
11,582 questions