我一直在试图追查了以下问题的WinForms应用程序:
本SynchronizationContext.Current是一个任务的延续(即空.ContinueWith这是主要的线程上运行)(我预计当前同步上下文是System.Windows.Forms.WindowsFormsSynchronizationContext).
以下是演示此问题的Winforms代码:
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TaskScheduler ts = TaskScheduler.FromCurrentSynchronizationContext(); // Get the UI task scheduler
// This line is required to see the issue (Removing this causes the problem to go away), since it changes the codeflow in
// \SymbolCache\src\source\.NET\4\DEVDIV_TFS\Dev10\Releases\RTMRel\ndp\clr\src\BCL\System\Threading\ExecutionContext.cs\1305376\ExecutionContext.cs
// at line 435
System.Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");
var task = Task.Factory.StartNew(() => { });
var cont …Run Code Online (Sandbox Code Playgroud) 我喜欢TPL中Parallel.For和Parallel.ForEach扩展方法的简单性.我想知道是否有办法利用类似的东西,甚至是稍微高级的任务.
下面是SqlDataReader的典型用法,我想知道是否可能,如果是这样,如何用TPL中的东西替换下面的while循环.因为读者不能提供固定数量的迭代,所以不能使用For扩展方法,这样就可以处理我将收集的任务.我希望有人可能已经解决了这个问题,然后找出了一些与ADO.net不同的事情.
using (SqlConnection conn = new SqlConnection("myConnString"))
using (SqlCommand comm = new SqlCommand("myQuery", conn))
{
conn.Open();
SqlDataReader reader = comm.ExecuteReader();
if (reader.HasRows)
{
while (reader.Read())
{
// Do something with Reader
}
}
}
Run Code Online (Sandbox Code Playgroud) 我想知道在使用TPL TaskFactory.FromAsync和使用TaskFactory.StartNew阻塞版本的方法之间是否存在性能影响.我正在编写一个TCP服务器,它将支持不超过100个并发连接.在使用第一个选项编写代码并使用continue来链接多个读写操作之后,我留下了丑陋,难以调试的代码.
我相信用同步版本编写代码然后用Task包装它会降低复杂性并提高可测试性,但是我担心这样做的性能影响.
例如,这两个调用之间是否存在任何性能差异:
NetworkStream stream;
byte[] data;
int bytesRead;
//using FromAsync
Task<int> readChunk = Task<int>.Factory.FromAsync (
stream.BeginRead, stream.EndRead,
data, bytesRead, data.Length - bytesRead, null);
//using StartNew with blocking version
Task<int> readChunk2 = Task<int>.Factory.StartNew(() =>
stream.Read(data, bytesRead, data.Length - bytesRead));
Run Code Online (Sandbox Code Playgroud) 我正在寻找一个TPL数据流块解决方案,它可以容纳多个项目,可以链接到多个目标块,但是它能够将项目转发到仅通过过滤器/谓词的特定目标块.在任何时候都不应该将项目同时传递到多个目标块,始终只能传递给与过滤器匹配的项目,或者可以丢弃该项目.我不喜欢BroadCastBlock,因为如果我理解正确,它不能保证传送(或者是吗?)并且过滤是在目标块侧完成的,这意味着BroadCastBlock基本上将每个项目的副本发送到所有linkedTo目标块.如果我理解正确,它也不会在任何时候持有多个项目.我不想使用Post/Async但维护LinkTo链.
有没有办法绕过完整的自定义数据流块?或者我误解了BroadCastBlock的工作原理?不幸的是,实际上没有太多文档可以详细介绍并涵盖用例.任何想法都受到高度赞赏.
我正在玩一点.NET的异步功能,并提出了一个我无法解释的情况.在同步ASP.NET MVC控制器中执行以下代码时
var t = Task.Factory.StartNew(()=>{
var ctx = System.Web.HttpContext.Current;
//ctx == null here
},
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext()
);
t.Wait();
Run Code Online (Sandbox Code Playgroud)
ctx是null委托范围内.根据我的理解,当您使用TaskScheduler.FromCurrentSynchronizationContext()任务调度程序时,应该恢复上下文.那么为什么不在这里呢?(我可以,顺便说一下,看到委托在同一个线程上同步执行).
此外,从msdn,a TaskScheduler.FromCurrentSynchronizationContext()应该表现如下:
排队到返回的调度程序的所有Task实例将通过在该上下文上调用Post方法来执行.
但是,当我使用此代码时:
var wh = new AutoResetEvent(false);
SynchronizationContext.Current.Post(s=> {
var ctx = System.Web.HttpContext.Current;
//ctx is set here
wh.Set();
return;
},null);
wh.WaitOne();
Run Code Online (Sandbox Code Playgroud)
实际上设置了上下文.
我知道这个例子有点做作,但我真的很想了解如何增加我对.NET上异步编程的理解.
今天我想知道如何通过等待每个任务来转换任务列表.请考虑以下示例:
private static void Main(string[] args)
{
try
{
Run(args);
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
}
static async Task Run(string[] args)
{
//Version 1: does compile, but ugly and List<T> overhead
var tasks1 = GetTasks();
List<string> gainStrings1 = new List<string>();
foreach (Task<string> task in tasks1)
{
gainStrings1.Add(await task);
}
Console.WriteLine(string.Join("", gainStrings1));
//Version 2: does not compile
var tasks2 = GetTasks();
IEnumerable<string> gainStrings2 = tasks2.Select(async t => await t);
Console.WriteLine(string.Join("", gainStrings2));
}
static IEnumerable<Task<string>> GetTasks()
{
string[] …Run Code Online (Sandbox Code Playgroud) 我有一个"高精度"计时器类,我需要能够启动,停止和暂停/恢复.为此,我将在互联网上找到的几个不同的例子捆绑在一起,但我不确定我是否正在使用asnyc/await正确的任务.
这是我的相关代码:
//based on http://haukcode.wordpress.com/2013/01/29/high-precision-timer-in-netc/
public class HighPrecisionTimer : IDisposable
{
Task _task;
CancellationTokenSource _cancelSource;
//based on http://blogs.msdn.com/b/pfxteam/archive/2013/01/13/cooperatively-pausing-async-methods.aspx
PauseTokenSource _pauseSource;
Stopwatch _watch;
Stopwatch Watch { get { return _watch ?? (_watch = Stopwatch.StartNew()); } }
public bool IsPaused
{
get { return _pauseSource != null && _pauseSource.IsPaused; }
private set
{
if (value)
{
_pauseSource = new PauseTokenSource();
}
else
{
_pauseSource.IsPaused = false;
}
}
}
public bool IsRunning { get { return !IsPaused && _task != null && …Run Code Online (Sandbox Code Playgroud) c# long-running-processes xamarin.ios task-parallel-library async-await
这会有点长,所以请耐心等待.
我在想默认任务scheduler(ThreadPoolTaskScheduler)的行为与默认的" ThreadPool" SynchronizationContext(后者可以通过await或显式地通过隐式引用)非常相似TaskScheduler.FromCurrentSynchronizationContext().它们都安排在随机ThreadPool线程上执行的任务.实际上,SynchronizationContext.Post只是打电话ThreadPool.QueueUserWorkItem.
但是,TaskCompletionSource.SetResult当从默认排队的任务中使用时,工作方式有一个微妙但重要的区别SynchronizationContext.这是一个简单的控制台应用程序说明它:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleTcs
{
class Program
{
static async Task TcsTest(TaskScheduler taskScheduler)
{
var tcs = new TaskCompletionSource<bool>();
var task = Task.Factory.StartNew(() =>
{
Thread.Sleep(1000);
Console.WriteLine("before tcs.SetResult, thread: " + Thread.CurrentThread.ManagedThreadId);
tcs.SetResult(true);
Console.WriteLine("after tcs.SetResult, thread: " + Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(2000);
},
CancellationToken.None,
TaskCreationOptions.None,
taskScheduler);
Console.WriteLine("before await tcs.Task, thread: " + Thread.CurrentThread.ManagedThreadId);
await tcs.Task.ConfigureAwait(true); …Run Code Online (Sandbox Code Playgroud) 我有一个服务可以说,
public interface ISomeService
{
Task<bool> DoSomeExpensiveCheckAsync(string parameter);
}
Run Code Online (Sandbox Code Playgroud)
我有这个课程来消费服务.它只需要做一些简单的空检查,然后返回服务响应.
public class SomeServiceConsumer
{
private readonly ISomeService _serviceClient;
public SomeServiceConsumer(ISomeService serviceClient)
{
_serviceClient = serviceClient;
}
public async Task<bool> DoSomething1Async(string someParameter)
{
if (string.IsNullOrWhiteSpace(someParameter))
{
return false;
}
return await _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
}
//No async or await keywords
public Task<bool> DoSomething2Async(string someParameter)
{
if (string.IsNullOrWhiteSpace(someParameter))
{
return Task.FromResult(false);
}
return _serviceClient.DoSomeExpensiveCheckAsync(someParameter);
}
}
Run Code Online (Sandbox Code Playgroud)
我应该做的DoSomething1Async还是DoSomething2Async?
根据这个答案,我不应该用不必要的东西包裹await但是我必须Task.FromResult(false)用于短路DoSomething2Async
但根据这个答案,有一些案例try/catch和 …
我已经 从Noseratio那里读到了这个问题,这个问题显示了一个在等待完成其操作之后TaskScheduler.Current不一样的行为.
答案指出:
如果没有执行任何实际任务,则与之
TaskScheduler.Current相同TaskScheduler.Default
这是真的.我已在这里看到它 :
TaskScheduler.Default
- 返回一个实例
ThreadPoolTaskSchedulerTaskScheduler.Current
- 如果从执行任务中调用将返回
TaskScheduler当前正在执行的任务- 如果从任何其他地方打电话将返回
TaskScheduler.Default
但转念一想,如果是这样,让我们做创建一个实际的Task(不只是Task.Yield()),并对其进行测试:
async void button1_Click_1(object sender, EventArgs e)
{
var ts = TaskScheduler.FromCurrentSynchronizationContext();
await Task.Factory.StartNew(async () =>
{
MessageBox.Show((TaskScheduler.Current == ts).ToString()); //True
await new WebClient().DownloadStringTaskAsync("http://www.google.com");
MessageBox.Show((TaskScheduler.Current == ts).ToString());//False
}, CancellationToken.None, TaskCreationOptions.None,ts).Unwrap();
}
Run Code Online (Sandbox Code Playgroud)
第一个Messagebox是"True",第二个是"False"
题:
如您所见,我确实创建了一个实际任务.
我可以理解为什么第一个MessageBox产量True.多数民众赞成:
如果从执行任务中调用,则返回当前正在执行的任务的TaskScheduler
而那个任务确实有ts发送的内容 …
c# ×8
async-await ×5
.net ×4
.net-4.0 ×1
actor ×1
ado.net ×1
asp.net ×1
asynchronous ×1
c#-4.0 ×1
linq ×1
task ×1
taskfactory ×1
tpl-dataflow ×1
winforms ×1
xamarin.ios ×1