我是 C# 中多线程的新手。这就是我想要做的。我有一个 sql server 表
create table dbo.temp(ID smallint not null, textfilename varchar(100) not null,isDone bit not null )
INSERT INTO dbo.temp(1,'textfile1.txt',0)
INSERT INTO dbo.temp(2,'textfile2.txt',0)
INSERT INTO dbo.temp(3,'textfile3.txt',0)
INSERT INTO dbo.temp(4,'textfile4.txt',0)
我有 ac# 程序,它使用此文本文件的内容并更新其他数据库表并设置 isdone=1。我知道如何做这个单线程。
public class Program
{
public static void Main()
{
public string filename = "";
try
{
string query = "SELECT ID,textfilename FROM [somedatabase].[dbo].[temp] WITH(NOLOCK) WHERE isdone = 0 ORDER BY ID;";
using (SqlConnection Conn= new SqlConnection(ConfigurationManager.ConnectionStrings["sqlConnStr"].ConnectionString))
{
Conn.Open();
using (SqlCommand cmd = new SqlCommand(query, Conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
fileid = reader.GetInt16(0).ToString();
filename = reader.GetString(1);
StartProcessingFiles(filename);
}
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
throw e;
}
}
public static void StartProcessingFiles(string filename)
{
//some business rules here
//after processing them
//Update [somedatabase].[dbo].[temp] SET isdone=1 where filename=filename
}
}
如何将其转换为多线程一次说 3 个文件
多线程用于受 CPU 限制的逻辑。您的数据库更新不太可能受到应用服务器 CPU 的限制。因此,您可能要考虑使用async
.
要做到这一点,首先要分解你的逻辑。定义一个单独的方法来检索文件名:
public IEnumerable<string> GetFileNames()
{
string query = "SELECT ID,textfilename FROM [somedatabase].[dbo].[temp] WITH(NOLOCK) WHERE isdone = 0 ORDER BY ID;";
using (SqlConnection Conn= new SqlConnection(connectionString))
{
Conn.Open();
using (SqlCommand cmd = new SqlCommand(query, Conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
var filename = reader.GetString(1);
yield return filename;
}
}
}
}
}
然后编写代码同时处理列表,异步:
public async Task ProcessFiles()
{
var files = GetFileNames();
var tasks = files.Select( fileName => ProcessFile(fileName) );
await Task.WhenAll(tasks);
}
要使其工作,也ProcessFile
必须是异步的:
public async Task ProcessFile(string fileName)
{
string query = "Update [somedatabase].[dbo].[temp] SET isdone=1 where filename=@fileName";
using (SqlConnection Conn= new SqlConnection(connectionString))
{
Conn.Open();
using (SqlCommand cmd = new SqlCommand(query, Conn))
{
cmd.Parameters.AddWithValue("@fileName", fileName);
await cmd.ExecuteNonQueryAsync();
}
}
}
由于该方法使用ExecuteNonQueryAsync
,它可以将控制权返回给调用者并允许下一个任务继续进行(请参阅如何让 yield 和 await 实现控制流?)。当您调用 时,所有任务都会同步WhenAll
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句