我目前正在再次使用C#并开发一个简单的应用程序,该应用程序发送广播消息并在Windows窗体上显示时显示。
我有一个包含两个线程的发现类,一个每30秒广播一次,另一个线程在套接字上侦听。由于阻塞调用,它位于一个线程中:
if (listenSocket.Poll(-1, SelectMode.SelectRead))
第一个线程的工作方式与类库中的定时器非常相似,它会广播数据包,然后休眠30秒。
现在原则上它工作正常,当收到数据包时我把它扔给一个事件,Winform将它放在一个列表中。问题始于表单,但主要的UI线程需要调用。现在我只有两个线程,对我而言,当线程数量增长时,从长远来看,它似乎并不是最有效的。
我已经探索了这些任务,但这些似乎更倾向于一次性的长期运行任务(非常类似于表单的后台工作者)。
我发现大多数线程示例都向控制台报告,并且没有Invoke和锁定变量的问题。
当我使用.NET 4.5时,我应该转移到任务还是坚持线程?
答案 0 :(得分:1)
如果您尝试从这样的线程更新GUI,异步编程仍会将应用程序的某些方面委托给不同的线程(线程池),那么您将遇到与常规线程类似的问题。
然而,async await中有许多技术可以让你委派给后台线程,但是还有一个等待点,说明当你完成那个有效地允许你更新的操作时,请继续在GUI线程上没有调用的GUI线程,并具有响应式GUI。我在谈论configureAwait。但也有其他技术。
如果您还不知道异步等待机制,这将花费您一些时间来学习所有这些新事物。但是你会发现它非常有益。 但是由您来决定是否愿意花几天时间学习并尝试一种对您来说不熟悉的技术。
谷歌有点异步等待,有一些来自Stephen Cleary的优秀文章,例如http://blog.stephencleary.com/2012/02/async-and-await.html
答案 1 :(得分:0)
首先,如果您担心可扩展性,您可能应该从容易扩展的方法开始。 public string FirstName
{
get {return _firstName;}
set {_firstName = value;}
}
会很好用。任务也基于ThreadPool
,它们允许更复杂的情况,例如按顺序触发的任务/线程(也基于条件),同步等。在您的情况下(服务器和客户端),这似乎是不必要的。
其次,我认为您担心瓶颈情况,多个线程会尝试访问UI或DB等公共资源。使用DB - 不用担心他们可以很好地处理多个访问。但是在UI或其他非多线程友好资源的情况下,您必须自己管理并行访问。我建议像BlockingCollection
这样的东西,这是一个很好的方式来实现"许多生产者,一个消费者"图案。这样你就可以有多个线程添加东西,只有一个线程从集合中读取它并将它传递给像UI这样的单线程资源。