, . :
async Task UpdateUIAsync(CancellationToken token)
{
while (true)
{
token.ThrowIfCancellationRequested();
await Dispatcher.Yield(DispatcherPriority.Background);
var data = await GetDataAsync(token);
this.TextBlock.Text = "data " + data;
}
}
async Task<int> GetDataAsync(CancellationToken token)
{
await Task.Delay(10, token).ConfigureAwait(false);
return new Random(Environment.TickCount).Next(1, 100);
}
, , await Dispatcher.Yield(DispatcherPriority.Background). , , , , .
[UPDATE] , , . Progress<T> ( ). , Progress<T> SynchronizationContext.Post, . , , , .
, Buffer<T>, / . async Task<T> GetData() . System.Collections.Concurrent, - ( , - ), WPF:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Threading;
namespace Wpf_21626242
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.Content = new TextBox();
this.Loaded += MainWindow_Loaded;
}
async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
try
{
var cts = new CancellationTokenSource(10000);
var token = cts.Token;
var buffer = new Buffer<int>();
var workerTask = Task.Run(() =>
{
var start = Environment.TickCount;
while (true)
{
token.ThrowIfCancellationRequested();
Thread.Sleep(50);
buffer.PutData(Environment.TickCount - start);
}
});
while (true)
{
await Dispatcher.Yield(DispatcherPriority.Background);
var result = await buffer.GetData(token);
((TextBox)this.Content).Text = result.ToString();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
public class Buffer<T>
{
volatile TaskCompletionSource<T> _tcs = new TaskCompletionSource<T>();
object _lock = new Object();
public async Task<T> GetData(CancellationToken token)
{
Task<T> task = null;
lock (_lock)
task = _tcs.Task;
try
{
var cancellationTcs = new TaskCompletionSource<bool>();
using (token.Register(() => cancellationTcs.SetCanceled(),
useSynchronizationContext: false))
{
await Task.WhenAny(task, cancellationTcs.Task).ConfigureAwait(false);
}
token.ThrowIfCancellationRequested();
return await task.ConfigureAwait(false);
}
finally
{
lock (_lock)
if (_tcs.Task == task && task.IsCompleted)
_tcs = new TaskCompletionSource<T>();
}
}
public void PutData(T data)
{
TaskCompletionSource<T> tcs;
lock (_lock)
{
if (_tcs.Task.IsCompleted)
_tcs = new TaskCompletionSource<T>();
tcs = _tcs;
}
tcs.SetResult(data);
}
}
}
}