在我的多线程应用程序中调用SQL会导致应用程序成为瓶颈吗?
我使用的逻辑是否有效且符合最佳实践?
static void Main(string[] args)
{
try
{
TcpListener listener = new TcpListener(IPAddress.Any, 8000);
TcpClient client;
listener.Start();
while (true) // Add your exit flag here
{
client = listener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(ThreadProc, client);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}//Main
private static void ThreadProc(object obj)
{
var client = (TcpClient)obj;
// Do your work here...
NetworkStream ns = client.GetStream();
using (StreamWriter writer = new StreamWriter(ns))
{
writer.WriteLine("220 SMTP server ready.");
writer.Flush();
using (StreamReader reader = new StreamReader(ns))
{
//parse + persist smtp message here...
//save email message parts to a Email table in SQL SVR(from, to, body...)
}
}
}//ThreadProc
答案 0 :(得分:0)
我接近这个的方法是让你有一个Queue,你可以添加你要解析和持久的东西,然后由一个线程池提供服务,甚至只有一个线程,这取决于预期的吞吐量。这里的关键是队列尽快得到服务,但是如果有积压则不会影响添加更多项目。
编辑:
你的场景中有很多未知数,所以我的解决方案同样含糊不清,但我应该解释一下。
你的问题的问题是我不知道你的sql会运行多长时间,或者如果它失败/超时应该采取什么行动,或者你期望排队或运行多少这些sql语句。
我的解决方案是首先提取面向公众的界面,以便a)排队操作和b)处理操作。这使您有机会在以后或甚至现在为更合适的事情切换排队机制。
因此,假设您正在排队工作项,并且数据库停止响应。突然间什么都没有得救。这会影响您的应用程序的功能吗?这里有任何交易问题吗?将工作项写入像MSMQ这样的东西可能会更好吗? SQL Server还有一个代理服务,可以根据需要提供相应的服务。
所以我不会添加任何代码,但请按照这些条款思考:
1)指定接口接口:
公共接口QueueWorkItem { void AddWorkItemToQueue(WorkItem item); }
public interface ConsumeWorkItem { bool ItemsInQueue {get;} WorkItem GetNextItem(); }
您不必使用这些,只是示例。
2)构建一个实现接口的类 这是有趣的一点,您必须担心线程和阻塞(查找生产者消费者模式)您可以始终使用线程池并让ConsumeWorkItem真的不做任何事情。
最后,让我们谈谈线程池。这很好,但你没有太多的控制权,并且不能保证其中运行的所有线程都是你的。
希望有所帮助。