Tag: multithreading

如何使用C#并行执行多个“Ping”

我试图计算一组服务器的平均往返时间。 为了加快速度,我想并行执行ping操作。 我写了一个名为AverageRoundtripTime()的函数,但它似乎有用,因为我不太了解multithreading,我想知道我做的是否还可以。 请看看我的代码,让我知道它是否正常,或者是否有更好的方法来实现我想要的: public void Main() { // Collection of hosts. List hosts = new List(); // Add 100 hosts to the collection. for (Int32 i = 0; i < 100; ++i) hosts.Add("www.google.com"); // Display the average round-trip time for 100 hosts. Console.WriteLine(AverageRoundtripTime(hosts)); } public Double AverageRoundtripTime(IEnumerable hosts) { // Collection of threads. List […]

在Windows服务中执行任务循环的最佳方法

我有一种方法可以向我们的客户发送一些短信,如下所示: public void ProccessSmsQueue() { SmsDbContext context = new SmsDbContext(); ISmsProvider provider = new ZenviaProvider(); SmsManager manager = new SmsManager(context, provider); try { manager.ProcessQueue(); } catch (Exception ex) { EventLog.WriteEntry(ex.Message, EventLogEntryType.Error); } finally { context.Dispose(); } } protected override void OnStart(string[] args) { Task.Factory.StartNew(DoWork).ContinueWith( ??? ) } 所以,我有一些问题: 我不知道方法运行需要多长时间; 该方法可以抛出exception,我想在EventLog上编写 我希望每10分钟在循环中运行此方法, 但只能在最后一次执行完成后运行。 我怎么能做到这一点? 我想过使用ContinueWith() ,但我仍然对如何构建整个逻辑有疑问。

最佳实践LongRunning任务创建

对于需要使用.Net 4中的Task API运行的后台线程,这是一个很好的设计吗? 我唯一担心的是,如果我们要取消该任务,我将如何做到这一点? 我知道我可以将ProgramEnding设置为true但我知道Task API中有一个CancellationToken 。 这只是一个示例代码示例,以便一个线程将添加到集合中,另一个线程将从中删除。 任务设置为LongRunning,因为这需要在程序运行时连续运行 private void RemoveFromBlockingCollection() { while (!ProgramEnding) { foreach (var x in DataInQueue.GetConsumingEnumerable()) { Console.WriteLine(“Task={0}, obj={1}, Thread={2}” , Task.CurrentId, x + ” Removed” , Thread.CurrentThread.ManagedThreadId); } } } private void button1_Click(object sender, EventArgs e) { DataInQueue = new BlockingCollection(); var t9 = Task.Factory.StartNew(RemoveFromBlockingCollection , TaskCreationOptions.LongRunning); for (int […]

如何在Windows Phone 7中的后台线程上的WriteableBitmap上呈现文本?

我试图在Windows Phone 7应用程序中的位图上呈现文本。 看起来或多或少类似于以下的代码在主线程上运行时可以正常工作: public ImageSource RenderText(string text, double x, double y) { var canvas = new Canvas(); var textBlock = new TextBlock { Text = text }; canvas.Children.Add(textBloxk); Canvas.SetLeft(textBlock, x); Canvas.SetTop(textBlock, y); var bitmap = new WriteableBitmap(400, 400); bitmap.Render(canvas, null); bitmap.Invalidate(); return bitmap; } 现在,由于我必须使用更复杂的东西渲染多个图像,我想在后台线程上渲染位图以避免无响应的UI。 当我使用BackgroundWorker执行此操作时, TextBlock的构造函数会抛出一个UnauthorizedAccessException声称这是一个无效的跨线程访问。 我的问题是:如何在不阻塞UI的情况下在位图上呈现文本? 请不要建议使用Web服务进行渲染。 我需要渲染大量图像,并且带宽成本不能满足我的需求,离线工作的能力是一项主要要求。 如果有另一种呈现文本的方法,解决方案不一定必须使用WriteableBitmap或UIElements 。 编辑 另一个想法:有没有人知道是否应该可以在另一个线程中运行UI消息循环,然后让该线程完成工作? […]

UWP:通过后台线程的数据绑定更新UI

我在我的UWP应用程序中使用x:Bind(编译绑定)将TextBlock绑定到ViewModel中的整数属性,该属性由值转换器转换为字符串。 我在工作线程的ViewModel中使用一个方法来设置属性并调用PropertyChanged事件。 但是,我得到一个exception(具体来说,它位于MainPage.g.cs文件中的XamlBindingSetters类中),“应用程序调用了一个为不同线程编组的接口。” 根据这篇文章 ,这应该在WPF中运行得很好; 在WinRT / UWP中删除了这种易用性,还是我做错了什么? 这正是我正在做的事情。 我的属性定义如下: private int myProperty; public int MyProperty { get { return myProperty; } set { Set(ref myProperty, value); } } Set方法是Template 10库的一部分,定义如下: public bool Set(ref T storage, T value, [CallerMemberName]string propertyName = null) { if (object.Equals(storage, value)) return false; storage = value; RaisePropertyChanged(propertyName); return true; } […]

C#监听器线程的CPU使用率很高,睡眠未命中断开

我的连接处理程序如下(这比个人实验更多,而不是生产代码) 如果我没有在while循环中的任何地方添加一个Thread.Sleep,它会开始吸收CPU。相反,如果我做睡眠以缓解无休止的垃圾邮件,我会错过断开连接.. CPU的比例正常上升对于运行的客户端/线程的数量,所以不是监听器本身导致高使用率,它是下面发布的实际客户端线程..任何人对如何解决这个问题都有任何想法? (我正在避免基于等待的解决方案,因为我对async / await不够熟悉,并且线程方法对于这个相当小的项目工作正常) 我只是在SO周围寻找解决方案,并没有注意到任何这个特定的问题,或者提供了除了指导人们异步/等待文章之外的解决方案,所以很抱歉,如果我错过了适用的答案。 private void HandleConnection(CancellationToken ct) { int recv = 0; byte[] buf = new byte[4096]; Trace.WriteLine($”{_name} Connected”); if (_ns.CanWrite && _client.Connected) { _ns.Write(Encoding.BigEndianUnicode.GetBytes(“■WEL”), 0, Encoding.BigEndianUnicode.GetBytes(“■WEL”).Length); try { while (_client.Connected && !ct.IsCancellationRequested) { while (!_ns.DataAvailable) { //first attempted solution Thread.Sleep(100); // miss discon if i sleep here } if (ct.IsCancellationRequested) […]

线程安全的memoization

让我们以Wes Dyer的函数memoization方法为出发点: public static Func Memoize(this Func f) { var map = new Dictionary(); return a => { R value; if (map.TryGetValue(a, out value)) return value; value = f(a); map.Add(a, value); return value; }; } 问题是,当从多个线程使用它时,我们可能遇到麻烦: Func f = … var f1 = f.Memoize(); … in thread 1: var y1 = f1(1); in thread 2: […]

在“杀死”c#之前检查线程是否完成了它的方法

我的程序中有2个线程。 1是处理GUI而另一个是进行一些文字自动化。 让我们称他们为GUIThread和WorkerThread。 WorkerThread使用递归循环遍历方法。 在执行自动化一词时,WorkerThread只能处于活动状态,用户必须能够停止自动化一词。 因此,我在GUI上实现了一个“停止”按钮,它只是杀死/终止WorkerThread。 但是,如果我在方法中间杀死WorkerThread,它有时会导致我的word文档出现问题(这是一个较长的故事),这就是为什么我要在检查之前检查WorkerThread是否已从方法完成/返回它。 当我点击“停止”按钮时,这就是我的代码所做的事情: //Stops the worker thread = stops word automation in process workerThread.Abort(); //This blocks the thread until the workerThread has aborted while (workerThread.IsAlive) ; 我自己对这个问题的建议/解决方法是有一个全局变量,我可以在每次输入WorkerThread时设置并留下一个方法,但这对我来说似乎不对。 我的意思是我认为必须有一种更简单的方法来处理它。

async和await关键字不会导致创建其他线程吗?

我糊涂了。 一个或多个Task如何在一个线程上并行运行? 我对并行性的理解显然是错误的。 MSDN的比特我无法理解: async和await关键字不会导致创建其他线程。 异步方法不需要multithreading,因为异步方法不能在自己的线程上运行。 该方法在当前同步上下文上运行,并且仅在方法处于活动状态时才在线程上使用时间。 ..和: 在启动任务和等待任务之间,您可以启动其他任务。 其他任务隐式并行运行,但不会创建其他线程。

为什么ConcurrentDictionary.GetOrAdd(key,valueFactory)允许调用valueFactory两次?

我使用并发字典作为线程安全的静态缓存,并注意到以下行为: 来自GetOrAdd上的MSDN文档 : 如果在不同的线程上同时调用GetOrAdd,可能会多次调用addValueFactory,但是对于每次调用,它的键/值对可能不会添加到字典中。 我希望能够保证工厂只被召唤一次。 是否有任何方法可以使用ConcurrentDictionary API执行此操作而无需借助我自己的单独同步(例如锁定valueFactory)? 我的用例是valueFactory在动态模块中生成类型,所以如果同时运行同一个键的两个valueFactories,我点击: System.ArgumentException: Duplicate type name within an assembly.