Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 头脑风暴解决方案——发送两封电子邮件_Multithreading_Email - Fatal编程技术网

Multithreading 头脑风暴解决方案——发送两封电子邮件

Multithreading 头脑风暴解决方案——发送两封电子邮件,multithreading,email,Multithreading,Email,寻找解决这个问题的方法。交易如下: 我们有一家公司正在向我们发送位于目录中的文件。在我们这方面,我们有一个windows服务,可以监视该目录中的任何传入文件。一旦服务运行并找到文件,它就会执行代码开始处理这些文件。该目录一次可以包含1到n个文件。例如,我们可能有1000个文件出现在目录中,windows服务会看到这些文件,并启动将数据放入数据库并发送电子邮件的过程 该进程以多线程异步方式运行。它抓取一个文件,将数据放入数据库,然后向某人发送电子邮件。这里的问题是,当两个进程运行时,它们都遇到相同

寻找解决这个问题的方法。交易如下:

我们有一家公司正在向我们发送位于目录中的文件。在我们这方面,我们有一个windows服务,可以监视该目录中的任何传入文件。一旦服务运行并找到文件,它就会执行代码开始处理这些文件。该目录一次可以包含1到n个文件。例如,我们可能有1000个文件出现在目录中,windows服务会看到这些文件,并启动将数据放入数据库并发送电子邮件的过程

该进程以多线程异步方式运行。它抓取一个文件,将数据放入数据库,然后向某人发送电子邮件。这里的问题是,当两个进程运行时,它们都遇到相同的代码,有时会为同一个人生成两封电子邮件。方法如下:

  • 去数据库看看我们的联系人是否在那里
  • 是的,他在那里,好的,检查“电子邮件标志栏”。。。有没有给他发过电子邮件
  • 不,好吧,给他发封电子邮件,把“电子邮件标志栏”标记为是(bool)
  • 发生的情况是,两个线程同时命中此方法并同时读取代码。两人都查看数据库,发现“email flag column”是NO。然后他们发送电子邮件并将这些列标记为YES。但由于这种情况发生得太快,线程(A)在线程(B)读取DB列之前没有机会标记该列

    我曾经考虑过,如果在这个方法中两个线程背对背的话,我可以输入一些代码来“等待”。像锁一样。但我们不能这样做。我现在唯一的解决办法就是不发电子邮件。并且有一个控制台应用程序,可以在一天中的特定时间运行,并向该列中有0(否)的人发送电子邮件。一旦发送电子邮件,我们将列标记为1(是)

    这可能不是最好的解决方案,这就是为什么我在这里,让你们中的一些可怕的聪明人帮助我想出一些性感的解决方案

    你需要一把锁

    一种方法是让流程在开始处理之前将电子邮件移动到私人文件夹(对于该流程)。只有一个进程可以移动文件。这是你的锁

    编辑

    如果您决定使用数据库在数据库中设置锁,请小心


    除非您在Windows Vista、7或Server 2008上执行一些特殊的Pinvoke以访问事务文件系统,否则您将始终面临将事务扩展到文件系统时出现问题的危险

    如果您有多个进程和同步问题,您需要某种中央锁,否则无法解决问题。他们需要沟通

    如果您绝对无法完成所描述的流程,请尝试使用中央“同步”服务器。它有原子键操作。让进程在抓取文件时设置一个密钥,只要它打开文件,并设置一个密钥说“我已经处理了这个文件,我是进程id X”。如果其他人锁定了该文件,他们将取消该过程。在发送邮件之前再次检查,以避免在打开文件和设置锁之间出现进一步的冲突问题


    您可以将密钥设置为在特定时间后自动过期。

    我会在读取电子邮件标志时更新它-使用SP或将select and update移动到同一事务中。例如,如果电子邮件发送失败,则您始终可以将其返回到0。

    如果您正在阅读和更新数据库,则使用事务处理是像您这样的场景的常见且可靠的解决方案。顺便说一句:因此不是讨论论坛;这是一个问答网站。从yyy中选择xxx进行更新将在数据库中设置一个锁。hummmm,因此,也许将SQL查询放入USING(c#)或事务块中可以实现此目的….?c#
    USING
    实际上与数据库并发性无关-数据库事务应该实现此目的。