C# 如何在asp.net中查询服务器端的并发进度条请求
我实现了进度条,在后台处理视频时向用户显示完成状态。它在单个实例上运行良好。但当两个并发的视频进程开始时,它就混在一起了 当两个不同的用户同时启动两个视频进程时,两个用户有时会看到来自视频进程1的混合进度状态,有时会看到来自另一个进程的混合进度状态 服务器端的视频进程使用静态变量启动C# 如何在asp.net中查询服务器端的并发进度条请求,c#,asp.net,C#,Asp.net,我实现了进度条,在后台处理视频时向用户显示完成状态。它在单个实例上运行良好。但当两个并发的视频进程开始时,它就混在一起了 当两个不同的用户同时启动两个视频进程时,两个用户有时会看到来自视频进程1的混合进度状态,有时会看到来自另一个进程的混合进度状态 服务器端的视频进程使用静态变量启动 public static MediaHandler _mhandler = new MediaHandler(); 通过发送到第页的进度指示 [WebMethod] public static string G
public static MediaHandler _mhandler = new MediaHandler();
通过发送到第页的进度指示
[WebMethod]
public static string GetProgressStatus()
{
return Math.Round(_mhandler.vinfo.ProcessingCompleted, 2).ToString();
}
进度条每隔几秒钟发送一次进度请求
现在我的问题是如何设置mediahandler对象,该对象一次只能针对一个实例
e、 g进度条01仅显示视频进程01的状态
及
进度条02仅显示视频进程02的状态请小心ASP.NET和静态-静态whatchagot在同一appdomain中的会话(用户)之间是全局的(根据类型给出或获取一些差异) 将用户信息保存在会话存储中。或者,有点疯狂,让一个静态媒体处理程序对象使用会话id处理多个会话,并使用会话id查询其进度。这听起来有点难闻,但可能是您想要的,除非您希望每个会话都能够生成自己的编码
请参阅(关于该主题的众多文章之一)。但是,Microsoft knowledgebase文章在我看来有点太不清楚了。在ASP.NET和static方面要小心——在同一appdomain中,静态whatchagot在会话(用户)之间是全局的(根据类型的不同,会有一些差异) 将用户信息保存在会话存储中。或者,有点疯狂,让一个静态媒体处理程序对象使用会话id处理多个会话,并使用会话id查询其进度。这听起来有点难闻,但可能是您想要的,除非您希望每个会话都能够生成自己的编码
请参阅(关于该主题的众多文章之一)。但是,Microsoft knowledgebase文章在我看来有点太不清楚了。我建议您为每个新的编码请求生成一个
Guid
,该请求将在编码生命周期中使用。此外,我还建议MediaHandler
不要是静态的,并且为每个编码任务创建一个新的()GetProgressStatus()
现在应该有一个Guid参数,以便您可以查询每个编码的进度
您将需要持久性(数据库、静态列表、MSMQ…等)来跟踪您的
MediaHandler
实例,或者跟踪当前处理编码的进度(如果是连续完成的)。我建议您为每个新编码请求生成一个Guid
,该请求将在编码生命周期内使用。此外,我还建议MediaHandler
不要是静态的,并且为每个编码任务创建一个新的()GetProgressStatus()
现在应该有一个Guid参数,以便您可以查询每个编码的进度
您将需要持久性(数据库、静态列表、MSMQ…等)来跟踪您的
MediaHandler
实例,或者跟踪当前处理编码的进度(如果是连续进行的)。这是一种非常简单的方法:
您是否考虑过使用静态列表
其中列表中的每个项都是运行后台进程的处理程序的实例。您需要标识每个处理程序,最简单的方法是为每个处理程序使用Guid
这是一个示例工作代码:
输出
如您所见,每个窗口启动一个新进程,每个窗口都独立更新
ASPX
无功定时器;
无功电流过程;
函数getProgress(){
$.ajax({
url:“LongTimeOperations.aspx/GetStatus”,
数据:“{”processID:“'+currentProcess+'''''}”,
contentType:'application/json;charset=utf-8;',
数据类型:“json”,
类型:“POST”,
async:true,
cache:false,
成功:功能(msg){
$(“#res”).append(“
”+msg.d);
var r=味精d;
if(typeof(r)=='undefined'| | r===null){
timer.stop();
}
},
错误:函数(hxr){
警报(hxr.responseText);
}
});
}
$(函数(){
$(“#开始”)。单击(函数(){
$.ajax({
url:'LongTimeOperations.aspx/StartProcess',
数据:“{}”,
contentType:'application/json;charset=utf-8;',
数据类型:“json”,
类型:“POST”,
async:true,
cache:false,
成功:功能(msg){
警报(msg.d);
currentProcess=msg.d;
timer=$.timer(getProgress,2000,true);
},
错误:函数(hxr){
警报(hxr.responseText);
}
});
});
});
代码隐藏
公共静态列表进程=新列表();
[网络方法]
公共静态Guid StartProcess()
{
互斥体互斥体=新互斥体();
mutex.WaitOne();
var star=Thread.CurrentThread.ManagedThreadId.ToString();
var p=newcurrentprocess(Guid.NewGuid());
增加(p);
var o=可观察的。开始(()=>
{
var cap=p;
对于(int i=0;i<10;i++)
{
《睡眠》(2000年);
var cp=processs.FirstOrDefault(x=>x.ID==
<head runat="server">
<title></title>
<script type="text/javascript" src="Scripts/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="Scripts/jquery.timer.js"></script>
<script type="text/javascript">
var timer;
var currentProcess;
function getProgress() {
$.ajax({
url: 'LongTimeOperations.aspx/GetStatus',
data: '{"processID": "' + currentProcess + '"}',
contentType: 'application/json; charset=utf-8;',
dataType: 'json',
type: "POST",
async: true,
cache: false,
success: function (msg) {
$("#res").append("<br/>" + msg.d);
var r = msg.d;
if (typeof (r) === 'undefined' || r === null) {
timer.stop();
}
},
error: function (hxr) {
alert(hxr.responseText);
}
});
}
$(function () {
$("#start").click(function () {
$.ajax({
url: 'LongTimeOperations.aspx/StartProcess',
data: '{}',
contentType: 'application/json; charset=utf-8;',
dataType: 'json',
type: "POST",
async: true,
cache: false,
success: function (msg) {
alert(msg.d);
currentProcess = msg.d;
timer = $.timer(getProgress, 2000, true);
},
error: function (hxr) {
alert(hxr.responseText);
}
});
});
});
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="button" id="start" value="Start Process" />
<p>
<div id="res"></div>
</p>
</div>
</form>
</body>
public static List<CurrentProcess> Processes = new List<CurrentProcess>();
[WebMethod]
public static Guid StartProcess()
{
Mutex mutex = new Mutex();
mutex.WaitOne();
var star = Thread.CurrentThread.ManagedThreadId.ToString();
var p = new CurrentProcess(Guid.NewGuid());
Processes.Add(p);
var o = Observable.Start(() =>
{
var cap = p;
for (int i = 0; i < 10; i++)
{
Thread.Sleep(2000);
var cp = Processes.FirstOrDefault(x => x.ID == cap.ID);
if (cp != null)
cp.Status = string.Format("Current Process ID: {0}, Iteration: {1}, Starting thread: {2}, Execution thread: {3}",
cp.ID.ToString(),
i.ToString(),
star,
Thread.CurrentThread.ManagedThreadId.ToString()
);
}
Processes.RemoveAll(x => x.ID == cap.ID);
}, Scheduler.NewThread);
mutex.ReleaseMutex();
mutex.Close();
return p.ID;
}
[WebMethod]
public static string GetStatus(Guid processID)
{
var p = Processes.FirstOrDefault(x => x.ID == processID);
if (p != null)
return p.Status;
return null;
}
}
public class CurrentProcess
{
public Guid ID { get; set; }
public string Status { get; set; }
public CurrentProcess (Guid id)
{
this.ID = id;
}
}
public static List<MediaHandler> _lst = new List<MediaHandler>();
public static string EncodeVideo(string Source, string Published)
{
MediaHandler _mhandler = new MediaHandler();
..............
..............
_mhandler.vinfo.ProcessID = Guid.NewGuid().ToString();
// unique guid to attach with each process to identify proper object on progress bar and get info request
// add media handler object in concurrent static list
_lst.Add(_mhandler);
return _mhandler.vinfo.ProcessID; // retuned unique identifier
}
[WebMethod]
public static string GetProgressStatus(string ProcessID)
{
string completed_process = "0";
if (_lst.Count > 0)
{
int i = 0;
for (i = 0; i <= _lst.Count - 1; i++)
{
if (_lst[i].vinfo.ProcessID == ProcessID)
{
completed_process = Math.Round(_lst[i].vinfo.ProcessingCompleted, 2).ToString();
}
}
}
return completed_process;
}
if (_lst[i].vinfo.ProcessingCompleted >= 100)
{
// remove from list of corrent processes if processes reach this point
// store all information of completed process and remove it from list of concurrent processes
// e.g
VideoInfo current_uploaded_video_info = _lst[i].vinfo;
_lst.Remove(_lst[i]);
}