PDA

View Full Version : Timer for ASP.NET



trang674
27-08-2002, 10:15
Tui đang dự định viết 1 Ứng dụng Web thi trắc nghiệm qua mạng nhưng đụng ngay vấn đề thời gian ngay: hiển thị giờ + kiểm tra hết giờ làm bài.
Xin quí vị cao thủ giúp đỡ xin cám ơn

White_Rose
28-08-2002, 01:56
theo em thì lưu thời điểm bắt đầu tải trang về, sau đó lấy thời điểm submit. Nếu quá thì failded.
Hoặc dùng JS để tự động submit, method submit (nhưng cái này không an toàn)

bpmtri
28-08-2002, 12:41
Tuỳ bạn thiết kế ứng dụng của bạn như thế nào, ví dụ như hiện toàn bộ câu hỏi thi trắc nghiệm trên một trang hay mỗi lần chỉ hiện một câu trắc nghiệm. Theo tôi, chỉ có cách dùng JavaScript để giải quyết việc này. Còn nếu giải quyết theo cách của bạn White_Rose thì đụng phải vấn đề đường truyền. Không công bằng cho người thi. Tôi có sử dụng một số phần mềm thi trắc nghiệm trên mạng (của các công ty dùng để kiểm tra sơ tuyển các ứng viên của họ, và thấy các chương trình này đều dùng JavaScript để hiển thị thời gian và tính giờ).
Code java cụ thể để làm việc hiển thị thời gian và tính giờ tương đối dễ viết và có nhiều trên mạng, nếu bạn cần, thì có thể liên lạc trực tiếp theo qua e-mail của tôi (bpmtri@yahoo.com), tôi sẽ giúp bạn.
Thân mến.

White_Rose
29-08-2002, 00:45
dùng JS không thôi thì mình đâu lấy được kết quả??? Quan trọng nhất là mình phải biết kết quả ra sao mà.

bpmtri
29-08-2002, 08:28
A`, chỉ dùng JS để tính thời gian thôi White_Rose thôi, trước sau gì thì bạn cũng phải submit form ve server xử lý chứ.

DTB
29-08-2002, 23:28
Dùng 1 biến Session để lưu thời điểm mà server gửi bài cho cilent để khi nhận lại bài giải thì so sánh với biến Session đó. đồng thời cũng là để tránh trường hợp người ta làm bài trong tình trạng offline rồi mới nối mạng để gửi bài giải.
Khi đó dùng Request.ServerVariables("HTTP_REFERER") sẽ cho ta biết trường hợp này. Tuy nhiên trường hợp này không cần thiết dùng Request.ServerVariables("HTTP_REFERER")
vì giải trong tình trạng offline rồi mới gửi bài đi thì bài giải sẽ trật chìa với đề bài . Thi trắc nghiệm thì các câu hỏi sẽ khác nhau cho mỗi lần. Ta sẽ lưu đề bài trên server, chỉ nhận submit phần bài giải. Không nhận lại phần đề bài để chấm. Phần đề bài đã gửi thì lưu trên biến Session hay trong database thì tùy ý. Đơn giản là lưu đáp án trên server rồi khi nhận bài giải thì so sánh với nó để cho điểm.

Ví dụ lưu trong database thì khi nhận bài giải ta tìm lại đáp án đã lưu khi gửi bài thi:
..........
SQLstring="SELECT.... FROM....WHERE mtime='" & Session("thoigianguibai")& "' AND hoten='"& Session("name") &"'"
oConect.Execute SQLstring
..........

Trên trang web đó cũng cần dùng Script cilent để tự động thu bài (tự động submit khi timeout).

JavaScript trên cilent: ví dụ thu bài sau 10 phút = 600 giây:

<BODY onload="javascript: i=setTimeout('baigiai.submit()',600000)">
<FORM ID=baigiai ACTION=chamdiem.aspx METHOD=POST>
<INPUT .....
<INPUT .....
<INPUT .....
</FORM>

Hiển thị thời gian của đồng hồ của máy cilent trên trang web thì dùng các hàm như là:

var c = ":";
d = new Date();
s += d.getHours() + c;
s += d.getMinutes() + c;
s += d.getSeconds() + c;
s += d.getMilliseconds();
....
và dùng setInterval để hiển thị liên tục sau khỏang thời gian nào đó 1 giây hay 5 giây tùy ý. Không cần thiết hiển thị thời gian bằng đồng hồ của server đâu.

----------

Không cần phải lo lắng về thời gian chênh lệch nhau vài giây do đường truyền nhanh chậm khác nhau. Trên đời này đâu có chuyện công bằng tuyệt đối.

Nhưng như vậy có nghĩa là chỉ có thể áp dụng trên mạng internet cho bài thi có thời gian dài (15 câu cho 15 phút hay hơn nữa). Nếu bài thi trắc nghiệm từng câu một, mỗi câu 1 phút thì chắc chỉ áp dụng được cho mạng cục bộ mà thôi.

Dùng javascript để tự động submit vẫn an toàn vì ta vẫn có kiểm tra trên server. Nếu thời gian chậm ở mức chấp nhận được thì vẫn là công bằng. Các bài thi chênh lệch nhau 0,5 - 1 điểm thì vẫn bình thường. Thi trắc nghiệm thường thì 1 phút chỉ được 1 câu mà 1 câu thường chỉ 1/4 - 1/2 điểm thôi.

Thi trắc nghiệm qua internet thì chỉ có trường hợp làm bài hộ thì đành chịu. Các trường hợp khác đều kiểm soát được.

thaodr
02-11-2005, 09:52
Các bạn thân mến!

Dùng javascript là cách đơn giản nhất để tính thời gian trong thi trắc nghiệm. Nhưng thực sự đó chỉ đơn giản với ai lập trình trên Java hoặc C thôi. Cồnối với những người dung ASP.NET và VB.NET thì quá là phức tạp. Bởi trong một ASP.NET project của VB.NET mọi thứ đều do server quản lý. Kể cả time cũng do server quản lý. Các khái niệm submit hầu như bị quên lãng...
Vì vậy trong VB.NET khi tạo một Webform thì ta có thể sử dụng component timer để tính thời gian. Đây còn gọi là Server timer có độ chính xác gần như tuyệt đối. Theo tài liệu của microsoft thì đây chính là timer mà chúng ta cần khi viết test trắc nghiệm.
Đen một nỗi, mình đã làm theo mọi chỉ dẫn của microsoft nhưng cái timer ấy vẫn không chịu làm việc. Event Elapsed hầu như không bao giờ sảy ra.
Trong khi dùng Winform thì chạy "như đồng hồ"...
Các bạn thử xem cái component timer đó nhé... Bởi trong VB.NET ta có thể bố trí cả bài thi chỉ trong 1 webform.
Nếu bạn nào nghiên cứu ra trước mail cho mình với nhé...

Thaodr@mail.ru

conkien2004
04-11-2005, 22:34
Các bạn thân mến!
Đen một nỗi, mình đã làm theo mọi chỉ dẫn của microsoft nhưng cái timer ấy vẫn không chịu làm việc. Event Elapsed hầu như không bao giờ sảy ra.
Trong khi dùng Winform thì chạy "như đồng hồ"...


Dùng System.Threading.Timer, System.Threading.Timer có thể dùng cho WinForm và WebForm, tất cả đều là the same!

[C#]
using System;
using System.Threading;

class TimerExample
{
static void Main()
{
AutoResetEvent autoEvent = new AutoResetEvent(false);
StatusChecker statusChecker = new StatusChecker(10);

// Create the delegate that invokes methods for the timer.
TimerCallback timerDelegate =
new TimerCallback(statusChecker.CheckStatus);

// Create a timer that signals the delegate to invoke
// CheckStatus after one second, and every 1/4 second
// thereafter.
Console.WriteLine("{0} Creating timer.\n",
DateTime.Now.ToString("h:mm:ss.fff"));
Timer stateTimer =
new Timer(timerDelegate, autoEvent, 1000, 250);

// When autoEvent signals, change the period to every
// 1/2 second.
autoEvent.WaitOne(5000, false);
stateTimer.Change(0, 500);
Console.WriteLine("\nChanging period.\n");

// When autoEvent signals the second time, dispose of
// the timer.
autoEvent.WaitOne(5000, false);
stateTimer.Dispose();
Console.WriteLine("\nDestroying timer.");
}
}

class StatusChecker
{
int invokeCount, maxCount;

public StatusChecker(int count)
{
invokeCount = 0;
maxCount = count;
}

// This method is called by the timer delegate.
public void CheckStatus(Object stateInfo)
{
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
Console.WriteLine("{0} Checking status {1,2}.",
DateTime.Now.ToString("h:mm:ss.fff"),
(++invokeCount).ToString());

if(invokeCount == maxCount)
{
// Reset the counter and signal Main.
invokeCount = 0;
autoEvent.Set();
}
}
}


http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingtimercallbackclasstopic.asp (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemthreadingtimercallbackclasstopic.asp)


Code sample trên hơi bị phức tạp, chỉ có 2 câu sau là quan trọng nhất:


TimerCallback timerDelegate =
new TimerCallback(statusChecker.CheckStatus);
Timer stateTimer =
new Timer(timerDelegate, autoEvent, 1000, 250);


Phần tô đỏ đỏ là function mà bác sẽ viết để làm 1 cái gì đó sau mỗi vòng lặp.
Để chạy sample trên webform, bác thay Console.WriteLine()= EventLog.WriteEntry() hoặc update 1 object nào đó trên Application, không dùng Response.Write().

Nếu mà viết ngắn lại thì như sau:


Timer stateTimer =
new Timer(new TimerCallback(statusChecker.CheckStatus), autoEvent, 1000, 250);


Nếu bác có function để làm gì đó khi hết giờ, ví dụ: public void HetGio();, ta thay vào thằng TimerCallback thì nó sẽ như thế này:


Timer stateTimer =
new Timer(new TimerCallback(HetGio), autoEvent, 1000, 250);


Definition của System.Threading.Timer:

public Timer ( System.Threading.TimerCallback callback , System.Object state , System.Int64 dueTime , System.Int64 period )