Tag: c# 5.0

使用Async await方法异步读取串行端口

我用这种方式从串口读取: public static void Main() { SerialPort mySerialPort = new SerialPort(“COM1”); mySerialPort.BaudRate = 9600; mySerialPort.Parity = Parity.None; mySerialPort.StopBits = StopBits.One; mySerialPort.DataBits = 8; mySerialPort.Handshake = Handshake.None; mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); mySerialPort.Open(); Console.WriteLine(“Press any key to continue…”); Console.WriteLine(); Console.ReadKey(); mySerialPort.Close(); } private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { SerialPort sp = (SerialPort)sender; string indata = […]

如何处理xUnit .net的Assert.Throws 中的Tasks抛出的exception?

以下异步xUnit.net测试使用标记有async修饰符的lambda失败,因为报告没有抛出exception: [Theory, AutoWebData] public async Task SearchWithNullQueryThrows( SearchService sut, CancellationToken dummyToken) { // Fixture setup // Exercise system and verify outcome Assert.Throws(async () => await sut.SearchAsync(null, dummyToken)); // Teardown } 为了确保实际抛出ArgumentNullException我明确地使用了try-catch块。 它工作,但结果代码不干净(与第一次测试相比): [Theory, AutoWebData] public async Task SearchWithNullQueryThrows( SearchService sut, CancellationToken dummyToken) { // Fixture setup var expected = typeof(ArgumentNullException); Type actual = null; // […]

为什么在取消大量HTTP请求时取消会阻塞这么长时间?

背景 我有一些代码使用来自一个特定主机的内容执行批量HTML页面处理。 它尝试使用HttpClient创建大量(~400)的同步HTTP请求。 我相信ServicePointManager.DefaultConnectionLimit限制了最大并发连接数,所以我没有应用自己的并发限制。 使用Task.WhenAll将所有请求异步发送到HttpClient Task.WhenAll ,可以使用CancellationTokenSource和CancellationToken取消整个批处理操作。 可以通过用户界面查看操作的进度,并且可以单击按钮以执行取消。 问题 对CancellationTokenSource.Cancel()的调用会阻塞大约5到30秒。 这会导致用户界面冻结。 怀疑是因为该方法正在调用注册取消通知的代码。 我考虑过什么 限制同时HTTP请求任务的数量。 我认为这是一种解决方法,因为HttpClient似乎已经HttpClient了过多的请求本身。 在非UI线程中执行CancellationTokenSource.Cancel()方法调用。 这不太好用; 在大多数其他任务完成之前,任务实际上并未运行。 我认为该方法的async版本可以很好地工作,但我找不到一个。 另外,我的印象是它适合在UI线程中使用该方法。 示范 码 class Program { private const int desiredNumberOfConnections = 418; static void Main(string[] args) { ManyHttpRequestsTest().Wait(); Console.WriteLine(“Finished.”); Console.ReadKey(); } private static async Task ManyHttpRequestsTest() { using (var client = new HttpClient()) using (var cancellationTokenSource […]

Cold Tasks和TaskExtensions.Unwrap

我有一个缓存类,它使用冷(未启动)任务来避免多次运行昂贵的东西。 public class AsyncConcurrentDictionary : System.Collections.Concurrent.ConcurrentDictionary<TKey, Task> { internal Task GetOrAddAsync(TKey key, Task newTask) { var cachedTask = base.GetOrAdd(key, newTask); if (cachedTask == newTask && cachedTask.Status == TaskStatus.Created) // We won! our task is now the cached task, so run it cachedTask.Start(); return cachedTask; } } 这很有效,直到你的任务实际使用C#5的await ,ala实现 cache.GetOrAddAsync(“key”, new Task(async () => { var […]

将async lambda表达式转换为委托类型System.Func ?

我有一个带有此签名的可移植类库中的异步方法: private async Task _Fetch(Uri uri) 它获取一个被回送为具体类型T的资源。 我正在使用第三方缓存库( Akavache ),它需要一个Func作为参数之一,并试图以这种方式这样做: await this.CacheProvider.GetOrCreateObject(key, async () => await _Fetch(uri), cacheExpiry); 这会导致错误: 无法将异步lambda表达式转换为委托类型’ System.Func ‘。 异步lambda表达式可能返回void , Task或Task ,其中任何一个都不能转换为’ System.Func ‘。 我已经尝试了Func赋值的各种排列而没有任何运气,我可以让代码工作的唯一方法是使Func阻塞: await this.CacheProvider.GetOrCreateObject(key, () => _Fetch(uri).Result, cacheExpiry); 哪个死了我的应用程序。 关于我误入歧途的任何指示?

我可以让我的程序集引用任何版本的另一个程序集吗?

我正在开发一个类库( MyClassLibrary )。 我依赖第三方类库( ThirdPartyClassLibrary )。 我需要使用相同版本的ThirdPartyClassLibrary作为我的用户。 例如,如果我在ThirdPartyClassLibrary设置静态值,则用户需要查看该更改。 我class级的用户可能依赖于ThirdPartyClassLibrary的4个不同版本中的任何一个。 ThirdPartyClassLibrary很大,我不想用我的软件分发它。 我已经反映了ThirdPartyClassLibrary所有4个版本,并validation了我将用它们做的事情在所有版本中是兼容的(接口是相同的,方法签名是相同的,等等)。 我需要调用ThirdPartyClassLibrary来提高性能! 每次我需要打电话时,我都无法反思所有事情。 MyClassLibrary将在运行时加载,因此我不能指望用户搞乱程序集绑定重定向或其他开发时设置(或任何设置,我的用户都无法做任何事情)。 我想从编译时检查我的代码中受益,所以理想情况下根本没有reflection。 我如何编写MyClassLibrary ,以便在加载到进程中时,一切都能正常运行,无论用户加载的是哪个版本的ThirdPartyClassLibrary ?

等待Task.Factory.StartNew(()=>与Task.Start;等待任务;

这两种使用等待forms之间是否有任何function差异? string x = await Task.Factory.StartNew(() => GetAnimal(“feline”)); Task myTask = new Task(() => GetAnimal(“feline”)); myTask.Start(); string z = await myTask; 具体来说,在1中调用每个操作的顺序是什么? 是StartNew被调用然后等待调用,还是等待在1中首先调用?

如何在执行Task.WhenAny时产生返回项

我的解决方案中有两个项目:WPF项目和类库。 在我的class级图书馆: 我有一个符号列表: class Symbol { Identifier Identifier {get;set;} List HistoricalQuotes {get;set;} List HistoricalFinancials {get;set;} } 对于每个符号,我查询金融服务,以使用webrequest检索每个符号的历史财务数据。 (webClient.DownloadStringTaskAsync(URI)) 所以这是我的方法: public async Task<IEnumerable> GetSymbolsAsync() { var historicalFinancialTask = new List<Task>(); foreach (var symbol in await _listSymbols) { historicalFinancialTask.Add(GetFinancialsQueryAsync(symbol)); } while (historicalFinancialTask.Count > 0) { var historicalFinancial = await Task.WhenAny(historicalFinancialTask); historicalFinancialTask.Remove(historicalFinancial); // the line below doesn’t compile, […]

调试异步/等待(调用堆栈)中的exception

我使用Async / Await释放我的UI-Thread并完成multithreading。 我遇到exception时遇到问题。 我的异步部分的Call Stack总是从ThreadPoolWorkQue.Dipatch()开始,这对我没有多大帮助。 我找到了MSDN文章Andrew Stasyuk。 Async Causality Chain跟踪它,但据我所知,它不是一个随时可用的解决方案。 如果在Async / Await中使用multithreading,最好/最简单的调试方法是什么?

如何衡量等待异步操作的性能?

我有一个从多个MessageQueue实例读取的Windows服务。 这些消息队列都运行自己的Task来读取消息。 通常,在阅读消息后,I / O数据库的工作就完成了。 我发现文章声称在I / O操作上使用异步是个好主意,因为它可以释放线程。 我正在尝试模拟在控制台应用程序中使用异步I / O操作的性能提升。 控制台应用程序 在我的测试环境中,我有10个队列。 GetQueues()返回10个不同的MessageQueue实例。 static void Main(string[] args) { var isAsync = Console.ReadLine() == “Y”; foreach (var queue in queueManager.GetQueues()) { var temp = queue; Task.Run(() => ReceiveMessagesForQueue(temp, isAsync)); } while (true) { FillAllQueuesWithMessages(); ResetAndStartStopWatch(); while(!AllMessagesRead()) { Thread.Sleep(10); } Console.WriteLine(“All messages read in {0}ms”, stopWatch.ElapsedMilliseconds); […]