我正在运行 Visual Studion 2010 (Net 4.0),我正在创建一个任务,将一些值加载到 ObservableCollection 中,然后返回到 UI。这是代码:
LoadValues = Task.Factory.StartNew<ObservableCollection<DataGridEntity>>(curDataLoader.LoadValuesTask);
ItemsList = LoadValues.Result;
this.DataContext = ItemsList;
Run Code Online (Sandbox Code Playgroud)
这段代码运行得很好!但使用 .Result 属性,UI 线程会等待,直到 LoadValues 任务返回。所以我想这样做:
LoadValues = Task.Factory.StartNew<ObservableCollection<DataGridEntity>>(curDataLoader.LoadValuesTask);
LoadValues.ContinueWith((FinishLoadDataToDataGrid1) =>
{
ItemsList = LoadValues.Result;
this.DataContext = ItemsList;
});
Run Code Online (Sandbox Code Playgroud)
差别很小。我使用ContinueWith 来防止UI 线程等待。但如果我这样做,他告诉我:“调用线程无法访问对象,因为不同的线程拥有它”在“this.DataContext = ItemsList;”
是不是时间问题?有人有什么想法吗?
为什么MemoryStream.ReadAsync正在使用任务,即使代码没有任何async或await。我确信async在这里使用不会带来任何性能提升,因为它不是 I/O 操作,而是内存中操作。
看起来好像使用了一些缓存,但它们仍然调用同步读取方法
Read(buffer, offset, count)
Run Code Online (Sandbox Code Playgroud)
那么这里的任务有什么用呢?
我知道如何取消任务,但找不到有关如何向 ValueTask 方法添加取消的任何信息。通常我会取消这样的任务:
public async Task<int> Foo(
CancellationToken cancellationToken)
{
TaskCompletionSource<int> tcsCancel =
new TaskCompletionSource<int>();
cancellationToken.Register(() =>
{
tcsCancel.TrySetCanceled();
});
Task<int> task = LongOperation();
var completedTask = await Task.WhenAny(
tcsCancel.Task,
task).ConfigureAwait(false);
return await completedTask.ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)
或者像这样:
if (cancellationToken.IsCancellationRequested)
return Task.FromCanceled<int>(cancellationToken);
Run Code Online (Sandbox Code Playgroud)
事实是,ValueTask 既没有 FromCanceled 也没有 WhenAny。我是不是应该做...
cancellationToken.ThrowIfCancellationRequested();
Run Code Online (Sandbox Code Playgroud) 下面是我的示例应用程序如何探索async/await&TPL
class Program
{
static async void Main(string[] args)
{
Console.WriteLine("Order for breakfast");
Breakfast obj = new Breakfast();
Task t1 = Task.Run(() => obj.MakeTea());
Task t2 = Task.Run(() => obj.ToastBread());
Task t3 = Task.Run(() => obj.BoilEgg());
Console.WriteLine("Breakfast ready");
var res = await Task.WaitAll(t1, t2, t3); // LOE - throwing error
}
}
class Breakfast
{
//making a tea
public string MakeTea()
{
return "tea";
}
//toasting bread
public string ToastBread()
{
return "bread";
}
//boil eggs
public …Run Code Online (Sandbox Code Playgroud) 典型情况:生产者快,消费者慢,需要让生产者慢下来。
无法按我预期工作的示例代码(解释如下):
// I assumed this block will behave like BlockingCollection, but it doesn't
var bb = new BufferBlock<int>(new DataflowBlockOptions {
BoundedCapacity = 3, // looks like this does nothing
});
// fast producer
int dataSource = -1;
var producer = Task.Run(() => {
while (dataSource < 10) {
var message = ++dataSource;
bb.Post(message);
Console.WriteLine($"Posted: {message}");
}
Console.WriteLine("Calling .Complete() on buffer block");
bb.Complete();
});
// slow consumer
var ab = new ActionBlock<int>(i => {
Thread.Sleep(500);
Console.WriteLine($"Received: {i}");
}, …Run Code Online (Sandbox Code Playgroud) 我是异步编程的新手。我的用户界面中有一个按钮和文本框。我想单击该按钮,它将使用 FileStream.ReadAsync 方法读取文件,然后它应该在文本框中显示文件的结果。问题是我不想在读取文件时阻止我的 UI。我认为使用 Read 方法应该这样做。但它不起作用。此方法有什么不正确以及如何将 Read 更改为 ReadAsync?
private void Button_Click(object sender, RoutedEventArgs e)
{
string filename = @"D:\Log\log.txt";
byte[] result;
UnicodeEncoding uniencoding = new UnicodeEncoding();
using (FileStream SourceStream = File.Open(filename, FileMode.Open))
{
result = new byte[SourceStream.Length];
Task<int> tf = new Task<int>(()=> SourceStream.Read(result, 0, (int)SourceStream.Length));
tf.ContinueWith((x) =>
{
try
{
string txt = Encoding.ASCII.GetString(result);
Dispatcher.BeginInvoke((Action)(() => txtBox.Text = txt));
}
catch (Exception ae)
{
MessageBox.Show(ae.Message);
}
});
tf.Start();
}
Run Code Online (Sandbox Code Playgroud) 我有一个 C# 控制台应用程序。在这个应用程序中,我有一个方法可以调用DoWorkAsync。对于此问题的上下文,此方法如下所示:
private async Task<string> DoWorkAsync()
{
System.Threading.Thread.Sleep(5000);
var random = new Random();
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var length = random.Next(10, 101);
await Task.CompletedTask;
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
Run Code Online (Sandbox Code Playgroud)
我DoWorkAsync从另一种方法调用,该方法确定 a) 这将运行多少次,以及 b) 每个调用是并行还是按顺序运行。该方法如下所示:
private async Task<Task<string>[]> DoWork(int iterations, bool runInParallel)
{
var tasks = new List<Task<string>>();
for (var i=0; i<iterations; i++)
{
if (runInParallel)
{
var task = Task.Run(() => DoWorkAsync());
tasks.Add(task);
}
else
{
await DoWorkAsync();
}
}
return tasks.ToArray(); …Run Code Online (Sandbox Code Playgroud) 在阅读了大量关于 await/async 的文章后,我仍然对这个主题有一些误解。请为我的问题提供简短的答案(是/否)和详细的答案,以便我更好地理解。
假设我们有以下方法:
public async Task UnresultTaskMethod()
{
await AsyncMethod1();
await AsyncMethod2();
}
Run Code Online (Sandbox Code Playgroud)
问题:
Task.WaitAll(tasks); Task.WhenAll(tasks);最后以便确保在所有任务结束之前不会继续执行时,这对我来说是主要的困惑因素,如果可以等待,为什么要以这种方式等待任务他们通过关键字等待?c# extension-methods multithreading task-parallel-library async-await
我有一个异步方法,它使用 HttpContext.Current,它由另一个在后台运行的代码使用,例如
var result = Task.Run(async () => await SomeMethod()).Result;
Run Code Online (Sandbox Code Playgroud)
HttpContext.Current 始终为 null。有没有办法将 HttpContext 传递给后台任务?
如果我们有 aaa 任务,并且为该任务创建一个延续(通过ContinueWith)TaskContinuationOptions.RunSynchronously,如果正在执行的方法ContinueWith如下:
static async Task SimpleMethodContinuationAsync(Task antecedentTask, object state)
{
// some very lightweight, thread-safe synchronous code.
await Task.Delay(5000); // Simulate async work.
// continuation of some more very lightweight, thread-safe synchronous code.
}
Run Code Online (Sandbox Code Playgroud)
await-之后的部分会有效释放开始执行任务延续的线程吗?这个续篇的其余部分将在哪个线程上继续?
SynchronizationContext上面的continuation的先行任务没有礼物时会问这个问题,但我听说SynchronizationContext不流经ContinueWith方法调用?真的吗?
c# ×9
async-await ×7
asynchronous ×3
.net-core ×2
asp.net ×1
c#-6.0 ×1
cancellation ×1
dataflow ×1
httpcontext ×1
task ×1
tpl-dataflow ×1