ASP.NET-MySQL为每行大容量插入异步响应
本文关键字:插入 异步 响应 大容量 NET-MySQL ASP | 更新日期: 2023-09-27 18:24:59
我正在创建一个web应用程序,需要上传一个客户列表进入数据库,列表将来自CSV、TSV或EXCEL文件。
这些文件可能包含50-200条记录
我需要一种方法,为数据库中的每一行插入都向客户端返回响应。例如成功或失败。
我不希望执行所有INSERTS,然后返回结果摘要。
我只需要知道怎么做。如果你不能提供代码也没关系。但如果可以的话当然更好。
请随时标记、编辑或重新标记。。
谢谢。顺致敬意,
我将尝试一个基于会话、javascript定时器和AJAX调用的答案。
客户端和服务器之间最常见的通信方式是,客户端因此向服务器请求一些东西。这是在带有计时器的JavaScript中实现的,当时间过去时,进行AJAX调用并创建一个新的计时器,该计时器将执行相同的操作。
在服务器上,您可以启用AJAX方法,这些方法将成为AJAX调用的入口点。该方法将以插入的状态进行响应。
由于您在两个地方处理插入,一个在执行插入的页面中,另一个在AJAX方法中(它是静态的,您无法访问page实例),因此您需要在一个单独的类中移动逻辑,并在会话中跟踪插入。
因此代码将如下所示:
public class CsvInserts
{
private IList<string> InsertsProgress {
get {
if (HttpContext.Current.Session["CsvInserts.Inserts"] == null )
HttpContext.Current.Session["CsvInserts.Inserts"] = new List<string>();
return (IList<string>)HttpContext.Current.Session["CsvInserts.Inserts"];
}
}
public IList<string> GetInsertsProgress() {
return InsertsProgress;
}
public void InsertFile(string[] lines) {
foreach ( var line in lines)
{
var row = DataAccess.CsvInserts.Insert(line); // code to insert the line
InsertsProgress.Add(row.GetRelevantInfoForUser()); // successfully inserted or not and which line was inserted
}
}
}
在插入页面上,您将执行以下操作
protected void btInsert_OnClick(object sender, EventArgs e)
{
var lines = .. get lines from the posted file;
var insertManager = new CsvInserts();
insertManager.InsertFile(lines);
}
WebMethod将是这样的
[WebMethod]
public static IList<string> GetInsertsProgress()
{
var insertManager = new CsvInserts();
return insertManager.GetInsertsProgress();
}
在使用该定时器的客户端,您将一次又一次地调用此方法,直到插入完成。用jQuery或其他东西显示接收到的字符串。
这段C#代码来自内存,更像是一条指南。很抱歉没有提供JavaScipt代码。此外,当插入完成或创建新的大容量插入时,必须清除字符串列表。
这里有一些类似的东西,代码可以编译并工作,但需要一些"工作",我们必须进行单行更新,其中,我更喜欢使用线程池进行ASP.Net异步调用,因为我们遇到了任务和未处理的异常等问题,总是编码器出错。
// In the FileUpload Event Handler, or other Event Handler raised to start the process
ThreadPool.QueueUserWorkItem(new WaitCallback(DataLoader.InsertClientRecords), new Tuple<string, Guid>("PathToFile.csv", uniqueIdentifier));
// In the Ajax callback (or WebMethod as previously proposed) to update the UI, possible update a GridView with results etc.
List<Tuple<Guid, int, bool, string>> updates = DataLoader.GetProgressReports(uniqueIdentifier);
// Static class
public static class DataLoader
{
private static readonly object locker = new object();
// Tuple Guid for unique Identifier, int RowNumber, bool Result, string Message (if any)
private static List<Tuple<Guid, int, bool, string>> results = new List<Tuple<Guid, int, bool, string>>();
public static void InsertClientRecords(object stateInfo)
{
// string FilePath, Guid for unique Identifier
Tuple<string, Guid> recordInfo = stateInfo as Tuple<string, Guid>;
if (recordInfo != null)
{
string filePath = recordInfo.item1;
Guid id = recordInfo.item1;
lock (locker)
{
// Update results List
}
}
}
// Tuple Guid for unique Identifier, int RowNumber, bool Result, string Message (if any)
public static List<Tuple<Guid, int, bool, string>> GetProgressReports(Guid identifier)
{
List<Tuple<Guid, int, bool, string>> updatedRecords = null;
bool lockTaken = false;
try
{
// 1000 Millisecond Timeout so the Ajax callback does not hang.
Monitor.TryEnter(locker, 1000, ref lockTaken);
if (lockTaken)
{
updatedRecords = results.Where(r => (r.Item1 == identifier)).ToList();
if (updatedRecords != null)
DataLoader.results.RemoveAll(r => (r.Item1 == identifier));
}
}
finally
{
if (lockTaken)
Monitor.Exit(locker);
}
return updatedRecords;
}