仅将线程用于Web服务调用,而不用于Db调用

时间:2013-01-10 15:24:33

标签: c# multithreading web-services sublist

我在c#中的应用就是这样做的。我启动尽可能多的线程,因为它是配置文件中的值(动态创建线程)。每个线程正在做的是:它进入DB,调用存储过程(如果我有60个线程,则存在死锁)。之后,每个线程都在调用Web服务,然后返回更新行。这是它的样子

List<Message> messages =getMessages(ThreadNO);//goes to DB

if (messages != null)
{
    foreach (Message bm in messages)
    {
        if (bm.Status)
        {
            try
            {
                bm.send();//calls Web service
            }
            catch (Exception ex)
            {
                LOG.Logger.Error(ex.ToString());
            }
            updateStatus(bm);//goes back to DB
        }
        else
        {
            if (bm.subscribe())
                updateSubscription(bm);//calls WS
            else
                updateUnsuccessfulSubscription(bm);//calls WS
        }
    }
}

我想以DB更便宜的方式做到这一点。我只想一次去DB,然后从对象消息创建子列表。之后我将创建与子列表一样多的线程,并将这些子列表传递给send()方法。每个线程都会调用send()方法。但是当我完成所有内容时,我怎样才能脱离线程并且只调用一次存储过程来更新(updateMessage()方法)? 如何才能以仅使用线程来调用Web服务,同时调用线程中的Db

4 个答案:

答案 0 :(得分:2)

我认为Parallel.ForEach()对您的情况很有用。

您要做的是从数据库中获取列表,然后使用Parallel.ForEach()并行处理项目,当它完成时,最后更新数据库。

类似的东西:

var messages = GetAllMessages(); //goes to DB

Parallel.ForEach(
    messages,
    new ParallelOptions { MaxDegreeOfParallelism = threadCount },
    message => { /* your code that calls the web service */ });

UpdateAll(messages); // goes back to the DB

Parallel.ForEach()并不保证会使用threadCount个线程,但在您的情况下,您很可能会很快达到该数字,因为调用了Web服务块。

答案 1 :(得分:0)

我不确定我是否完全理解您的问题,但如果您想将数据库调用限制为一次,则可以使用lock:

// put this field in a class somewhere
static object gate = new object();

// then wrap all your database calls in locks:
lock( gate )
{
  updateStatus(bm);
}

这样,有多少线程尝试同时调用数据库并不重要,一次只能运行一个调用。

答案 2 :(得分:0)

您应该查看消费者/生产者模式,例如参见http://en.wikipedia.org/wiki/Producer-consumer_problem

您的初始化将访问数据库并启动生成器(每个都是一个单独的线程)。这些将调用Web服务并将状态记录在共享的内存中数据结构(队列)中。

单个使用者(线程)将在共享队列中查找元素,并将它们保存在数据库中并从队列中删除。

答案 3 :(得分:0)

首先在一个帖子上选择

然后使用线程来完成消息的收集(我会使用Parallel.ForEach,滚动你自己的线程会花费很多麻烦)

现在你的选择超出了你可以进行更新的方式,但即使在一个线程中,你仍然可以通过其他任务获得死锁,你的代码应该期待并处理它。