如果我在方法中使用以下代码块(使用.NET 4和任务并行库):
var task = new Task(() => DoSomethingLongRunning());
task.Start();
Run Code Online (Sandbox Code Playgroud)
并且该方法返回,该任务是否超出范围并被垃圾收集,或者它将运行完成?我没有注意到GCing的任何问题,但是我想确保我没有为GC设置竞争条件.
我想使用这个Task <>构造函数.我似乎无法得到正确的sntax可以有人纠正我的代码.
另外,我是否正确地认为,如果一个任务是以这种方式构建的,那么它是不是已经开始了?
我认为我需要的构造函数:
Task<TResult>(Func<Object, TResult>, Object)
Run Code Online (Sandbox Code Playgroud)
我的代码错误:
参数1:无法从'方法组'转换为'
System.Func<object,int>'
static void Main(string[] args)
{
var t = new Task<int>(GetIntAsync, "3"); //error is on this line
...
}
static async Task<int> GetIntAsync(string callerThreadId)
{
...
return someInt;
}
Run Code Online (Sandbox Code Playgroud) 什么时候会选择使用Rx而不是TPL,或者2个框架是否正交?
根据我的理解,Rx主要用于提供事件的抽象并允许组合,但它也允许提供异步操作的抽象.使用Createxx重载和Fromxxx重载并通过处理返回的IDisposable取消.
TPL还通过任务和取消功能提供操作抽象.
我的困境是什么时候使用哪种情况?
该接受的答案质疑"为什么这个Parallel.ForEach代码冻结程序吗?" 建议在WPF应用程序中用ConcurrentBag替换List使用.
我想了解是否可以在这种情况下使用BlockingCollection?
我在这里有以下代码
public static async Task<string> Start(IProgress<ProcessTaskAsyncExProgress> progress)
{
const int total = 10;
for (var i = 0; i <= total; i++)
{
await Task.Run(() => RunLongTask(i.ToString(CultureInfo.InvariantCulture)));
if (progress != null)
{
var args = new ProcessTaskAsyncExProgress
{
ProgressPercentage = (int)(i / (double)total * 100.0),
Text = "processing " + i
};
progress.Report(args);
}
}
return "Done";
}
private static string RunLongTask(string taskName)
{
Task.Delay(300);
return taskName + "Completed!";
}
Run Code Online (Sandbox Code Playgroud)
在这一行:
var val = await Task.Run(() => RunLongTask(i.ToString(CultureInfo.InvariantCulture))).Result;
Run Code Online (Sandbox Code Playgroud)
如何获取RunLongTask的字符串值?
我试过了 …
快问,我想在启动没有返回值的异步任务之前等待一秒钟.
这是正确的方法吗?
Task.Delay(1000)
.ContinueWith(t => _mq.Send(message))
.Start();
Run Code Online (Sandbox Code Playgroud)
异常会发生什么?
我的应用程序有问题:在某些时候,SynchronizationContext.Current对主线程变为null.我无法在一个孤立的项目中重现同样的问题.我的真实项目很复杂; 它混合使用Windows窗体和WPF并调用WCF Web服务.据我所知,这些都是可以与SynchronizationContext交互的系统.
这是我孤立项目的代码.我真正的应用程序做了类似的事情.但是,在我的实际应用程序中,执行继续任务时,主线程上的SynchronizationContext.Current为null.
private void button2_Click(object sender, EventArgs e)
{
if (SynchronizationContext.Current == null)
{
Debug.Fail("SynchronizationContext.Current is null");
}
Task.Factory.StartNew(() =>
{
CallWCFWebServiceThatThrowsAnException();
})
.ContinueWith((t) =>
{
//update the UI
UpdateGUI(t.Exception);
if (SynchronizationContext.Current == null)
{
Debug.Fail("SynchronizationContext.Current is null");
}
}, CancellationToken.None,
TaskContinuationOptions.OnlyOnFaulted,
TaskScheduler.FromCurrentSynchronizationContext());
}
Run Code Online (Sandbox Code Playgroud)
什么可能导致主线程的SynchronizationContext.Current变为null?
编辑:
@Hans要求堆栈跟踪.这里是:
at MyApp.Framework.UI.Commands.AsyncCommand.HandleTaskError(Task task) in d:\sources\s2\Framework\Sources\UI\Commands\AsyncCommand.cs:line 157 at System.Threading.Tasks.Task.c__DisplayClassb.b__a(Object obj) at System.Threading.Tasks.Task.InnerInvoke() at System.Threading.Tasks.Task.Execute() at System.Threading.Tasks.Task.ExecutionContextCallback(Object obj) at System.Threading.ExecutionContext.runTryCode(Object userData) at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, …
我们使用IEnumerables从数据库中返回大量数据集:
public IEnumerable<Data> Read(...)
{
using(var connection = new SqlConnection(...))
{
// ...
while(reader.Read())
{
// ...
yield return item;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们想使用异步方法来做同样的事情.但是,async没有IEnumerables,因此我们必须将数据收集到列表中,直到加载整个数据集:
public async Task<List<Data>> ReadAsync(...)
{
var result = new List<Data>();
using(var connection = new SqlConnection(...))
{
// ...
while(await reader.ReadAsync().ConfigureAwait(false))
{
// ...
result.Add(item);
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
这将消耗服务器上的大量资源,因为所有数据必须在返回之前在列表中.IEnumerables处理大数据流的最佳且易于使用的异步替代方法是什么?我想避免在处理时将所有数据存储在内存中.
我是TPL的新手,我想知道:C#5.0中新增的异步编程支持(通过new async和await关键字)如何与线程的创建有关?
具体来说,async/await每次使用它们时是否使用创建新线程?如果有许多嵌套方法使用async/await,是否为每个方法创建了一个新线程?
更新这个问题的目的是得到一个简单的答案Task.Run()和死锁.我非常理解不混合异步和同步的理论推理,我将它们铭记于心.我不是在向别人学习新事物; 我尽力做到这一点.有时候所有人都需要技术答案......
我有一个Dispose()需要调用异步方法的方法.由于95%的代码都是异步的,因此重构不是最佳选择.拥有IAsyncDisposable框架支持的(以及其他功能)将是理想的,但我们还没有.所以在同一时间,我需要找到一种可靠的方法从同步方法调用异步方法而不会发生死锁.
我宁愿不使用,ConfigureAwait(false)因为这使得责任分散在我的整个代码中,以便被调用者以某种方式行事,以防调用者是同步的.我宁愿在同步方法中做一些事情,因为它是一个不正常的bugger.
在阅读了Stephen Cleary关于另一个Task.Run()总是在线程池中调度甚至异步方法的问题的评论后,它让我思考.
在ASP.NET中的.NET 4.5或任何其他同步上下文中,将任务调度到当前线程/同一线程,如果我有一个异步方法:
private async Task MyAsyncMethod()
{
...
}
Run Code Online (Sandbox Code Playgroud)
我想从同步方法中调用它,我可以使用Task.Run()它Wait()来避免死锁,因为它将异步方法排队到线程池吗?
private void MySynchronousMethodLikeDisposeForExample()
{
// MyAsyncMethod will get queued to the thread pool
// so it shouldn't deadlock with the Wait() ??
Task.Run((Func<Task>)MyAsyncMethod).Wait();
}
Run Code Online (Sandbox Code Playgroud)