Kiểm tra trạng thái chương trình MQL và lý do kết thúc
Chúng ta đã gặp hàm IsStopped
trong nhiều ví dụ khác nhau xuyên suốt cuốn sách. Hàm này cần được gọi định kỳ trong các trường hợp chương trình MQL thực hiện các phép tính dài. Điều này cho phép bạn kiểm tra xem người dùng có khởi tạo việc đóng chương trình hay không (tức là liệu họ có cố gắng xóa nó khỏi biểu đồ hay không).
bool IsStopped() ≡ bool _StopFlag
Hàm trả về true
nếu chương trình bị người dùng gián đoạn (ví dụ, bằng cách nhấn nút Delete trong hộp thoại được mở bằng lệnh Expert List trong menu ngữ cảnh).
Chương trình được cho 3 giây để tạm dừng tính toán một cách hợp lý, lưu kết quả trung gian nếu cần, và hoàn thành công việc của nó. Nếu điều này không xảy ra, chương trình sẽ bị xóa khỏi biểu đồ một cách cưỡng chế.
Thay vì hàm IsStopped
, bạn có thể kiểm tra giá trị của biến tích hợp StopFlag
.
Script thử nghiệm EnvStop.mq5
mô phỏng các phép tính dài trong một vòng lặp: tìm kiếm số nguyên tố. Điều kiện thoát khỏi vòng lặp while
được viết bằng hàm IsStopped
. Do đó, khi người dùng xóa script, vòng lặp bị gián đoạn theo cách thông thường và nhật ký hiển thị thống kê về các số nguyên tố được tìm thấy (script cũng có thể lưu các số này vào một tệp).
bool isPrime(int n)
{
if(n < 1) return false;
if(n <= 3) return true;
if(n % 2 == 0) return false;
const int p = (int)sqrt(n);
int i = 3;
for( ; i <= p; i += 2)
{
if(n % i == 0) return false;
}
return true;
}
void OnStart()
{
int count = 0;
int candidate = 1;
while(!IsStopped()) // thử thay thế bằng while(true)
{
// mô phỏng tính toán dài
if(isPrime(candidate))
{
Comment("Count:", ++count, ", Prime:", candidate);
}
++candidate;
Sleep(10);
}
Comment("");
Print("Total found:", count);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Nếu chúng ta thay đổi điều kiện vòng lặp thành true
(vòng lặp vô hạn), script sẽ ngừng phản hồi yêu cầu dừng của người dùng và sẽ bị gỡ khỏi biểu đồ một cách cưỡng chế. Kết quả là, chúng ta sẽ thấy lỗi "Abnormal termination" trong nhật ký, và chú thích ở góc trên bên trái của cửa sổ vẫn không được xóa sạch. Do đó, tất cả các lệnh trong ví dụ này tượng trưng cho việc lưu dữ liệu và giải phóng tài nguyên đang sử dụng (ví dụ, có thể là xóa các đối tượng đồ họa của chính nó khỏi cửa sổ) sẽ bị bỏ qua.
Sau khi yêu cầu dừng đã được gửi đến chương trình (và giá trị StopFlag
bằng true
), lý do kết thúc có thể được tìm ra bằng hàm UninitializeReason
.
Lưu ý: Đáng tiếc, tính năng này chỉ khả dụng cho Expert Advisors và chỉ báo.
int UninitializeReason() ≡ int _UninitReason
Hàm trả về một trong những mã được định nghĩa trước mô tả lý do hủy khởi tạo.
Hằng số | Giá trị | Mô tả |
---|---|---|
REASON_PROGRAM | 0 | Hàm ExpertRemove chỉ khả dụng trong Expert Advisors và script đã được gọi |
REASON_REMOVE | 1 | Chương trình bị xóa khỏi biểu đồ |
REASON_RECOMPILE | 2 | Chương trình được biên dịch lại |
REASON_CHARTCHANGE | 3 | Biểu tượng hoặc chu kỳ của biểu đồ thay đổi |
REASON_CHARTCLOSE | 4 | Biểu đồ bị đóng |
REASON_PARAMETERS | 5 | Tham số đầu vào của chương trình thay đổi |
REASON_ACCOUNT | 6 | Một tài khoản khác được kết nối hoặc kết nối lại với máy chủ giao dịch |
REASON_TEMPLATE | 7 | Một mẫu biểu đồ khác được áp dụng |
REASON_INITFAILED | 8 | Trình xử lý sự kiện OnInit trả về cờ lỗi |
REASON_CLOSE | 9 | Terminal bị đóng |
Thay vì hàm, bạn có thể truy cập biến toàn cục tích hợp UninitReason
.
Mã lý do hủy khởi tạo cũng được truyền dưới dạng tham số cho hàm xử lý sự kiện OnDeinit.
Sau này, khi nghiên cứu Tính năng khởi động và dừng chương trình, chúng ta sẽ thấy một chỉ báo (Indicators/MQL5Book/p5/LifeCycle.mq5
) và một Expert Advisor (Experts/MQL5Book/p5/LifeCycle.mq5
) ghi lại lý do hủy khởi tạo và cho phép bạn khám phá hành vi của chương trình tùy thuộc vào hành động của người dùng.