我有一个非常大的网络图像数据库,我正在分类(在本地下载)。
所以我有一个网站(本地)来做这个,但数据库查询花了很长时间,所以我有一个想法" preload"下一页,这样只有页面的第一次加载才会很慢。我保存会话中单独线程中加载的项目列表。到现在为止还挺好。 我想进一步优化,并对最长时间进行一些测试,并加载图像以检查尺寸,看看是否需要缩放它们(在img obj上设置图像高度和宽度) - 所以我想这样做使用parallel.foreach循环 - 但在执行此操作后,我的页面上的按钮停止响应?当我按下按钮时,我可以看到页面在page_load事件中运行,但它没有到达按钮" code": protected virtual void btnSaveFollowPosts_Click(object sender,EventArgs e) {...}
对我做错的任何看法?我试图将paralellelism的程度限制为1只是为了看看是否会解决它 - 但事实并非如此。
更新 - 代码: 试图把它煮沸:
protected void Page_Load(object sender, EventArgs e)
{
Search(false);
}
protected void Search(bool updateCounters)
{
if (Session[SessionItems] == null)
{
if (Session[SessionItemsCache] == null)
{
//if is being constructed, wait, else construct
//if construction is not running
if (Session[SessionCacheConstructionRunning] == null)
{
StartPreLoadContent();
}
while (Session[SessionCacheConstructionRunning] != null)
{
Thread.Sleep(25); //block main thread untill items ready
}
}
List<ContentView> contentViewList = Session[SessionItemsCache] as List<ContentView>;
Session[SessionItemsCache] = null; //clean preload cache
Session[SessionItems] = contentViewList; //save in current usage storage
Filltable(ref tblContent, contentViewList);
//preload next batch
StartPreLoadContent();
}
else
{
List<ContentView> contentViewList = Session[SessionItems] as List<ContentView>; //get items from session
Session[SessionItems] = contentViewList; //save in current usage storage
Filltable(ref tblContent, contentViewList);
}
}
protected void StartPreLoadContent()
{
Session[SessionCacheConstructionRunning] = true;
//start task
Thread obj = new Thread(new ThreadStart(RunPreLoadContent));
obj.IsBackground = true;
obj.Start();
}
protected void RunPreLoadContent()
{
using (DBEntities entities = new DBEntities())
{
entities.CommandTimeout = 86400;
IQueryable<ContentView> query = entities.ContentView.Where(some criterias);
List<ContentView> contentViewListCache = query.ToList();
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 7;
Parallel.ForEach(contentViewListCache, options, content =>
{
try
{
Interlocked.Increment(ref imageSizeCount);
string path = Path.Combine(basePath, content.LocalPath);
int imageSize = 150;
using (System.Drawing.Image realImage = System.Drawing.Image.FromFile(path))
{
double scale = 0;
if (realImage.Height > realImage.Width)
{
scale = (double)realImage.Height / imageSize;
}
else
{
scale = (double)realImage.Width / imageSize;
}
if (scale > 1)
{
content.ImageHeight = (int)((double)realImage.Height / scale);
content.ImageWidth = (int)((double)realImage.Width / scale);
content.ImageScaled = true;
}
content.ShowImage = true;
}
}
catch (Exception)
{
}
});
Session[SessionItemsCache] = contentViewListCache;
Session[SessionCacheConstructionRunning] = null; //cache ready
}
protected virtual void btnSave_Click(object sender, EventArgs e)
{
try
{
//save
...some reading and saving going on here...
//update
Session[SessionItems] = null;
Search(true);
}
catch (Exception error)
{
ShowError(error);
}
}
答案 0 :(得分:1)
我同意之前的评论:您可能应该在页面生命周期的早期执行此逻辑。考虑重写OnInit并将其放在那里。
此外,您可以尝试这行代码而不是当前的线程代码(更适合Windows而不是Web编程):
using System.Threading.Tasks;
Task.Run(() => { RunPreLoadContent(); });