2011-01-02 47 views
7

tôi đã thực hiện một trò chơi động cơ vòng lặp như sau:Có các phương pháp hay nhất để triển khai vòng lặp trò chơi không đồng bộ không?

public static Boolean Start () 
{ 
    if (hasBoard) 
    { 
     // start engine on worker thread 
     asyncTask = new AsyncResult (stopEngine, asyncTask); 
     isRunning = ThreadPool.QueueUserWorkItem (startEngine, asyncTask); 

     if (isRunning) 
     { 
      Console.WriteLine ("[{0}] Engine started", 
       DateTime.Now.ToString ("hh:mm:ss")); 
     } 
     else 
     { 
      Console.WriteLine ("[{0}] Engine failed to start", 
       DateTime.Now.ToString ("hh:mm:ss")); 
     } 
    } 

    return isRunning; 
} 

public static void Stop () 
{ 
    Console.WriteLine ("[{0}] Engine stopping", 
     DateTime.Now.ToString ("hh:mm:ss")); 

    asyncTask.SetAsCompleted (null, false); 
} 

private static void startEngine (Object task) 
{ 
    while (!((IAsyncResult)task).IsCompleted) 
    { 
     Thread.Sleep (10000); 

     Console.WriteLine ("[{0}] Engine running", 
      DateTime.Now.ToString ("hh:mm:ss")); 
    } 
} 

private static void stopEngine (IAsyncResult iaResult) 
{ 
    // clean up resources 

    Console.WriteLine ("[{0}] Engine stopped", 
     DateTime.Now.ToString ("hh:mm:ss")); 

    isRunning = false; 
} 

Tôi đang sử dụng lớp AsyncResult khuyến cáo của Jeff Richter trong bài viết của mình, Implementing the CLR Asynchronous Programming Model. Để có thể dừng động cơ từ giao diện người dùng, việc triển khai tôi đã sử dụng hơi lệch so với mẫu không đồng bộ chuẩn. Việc triển khai này hoạt động như mong đợi, nhưng khi tôi chuyển hướng từ một thực hành tiêu chuẩn, tôi trở lại cộng đồng SO để đảm bảo tôi đang làm đúng cách.

Có bất kỳ vấn đề nào với việc triển khai này mà mọi người có thể thấy không?

+0

trong vòng lặp công cụ trò chơi, bạn sẽ không tạo ra một chuỗi mới thay vì sử dụng một chuỗi hồ bơi? –

+0

@Mitch: Tôi không chắc lắm. Tôi tin rằng việc sinh ra một sợi mới là tiêu chuẩn. Tôi không biết rằng có bất cứ điều gì sai trái với việc sử dụng một Threadpool thread. Động cơ trò chơi này là siêu nhẹ. Ngoài ra, kể từ khi một giao diện người dùng WinForms là * trong kiểm soát *, tôi nghĩ đây sẽ là một cách tốt để làm việc vòng lặp trò chơi. – IAbstract

+1

Tại sao bạn sử dụng * chủ đề * bất kỳ trong một vòng lặp trò chơi? Nếu bạn cần * bất kỳ (mà thực sự nên được đặt câu hỏi), các chủ đề có thể là các luồng được tạo sẵn cho một mục đích * xác định rõ ràng * (ví dụ: luôn luôn 2 luồng, v.v ... liên tục hoạt động) hoặc đồng bộ hóa khác. Tuy nhiên, tốt nhất có thể chỉ để giữ nó "KISS". –

Trả lời

11

Vì âm thanh này giống như một dự án bạn có quyền kiểm soát, tôi khuyên bạn nên bỏ APM và sử dụng mô hình dựa trên Task được cung cấp trong .NET4. Đây là phương pháp được khuyến nghị cho .NET4 thay vì APM. Lớp Task là một phần của Thư viện song song công việc (TPL) nhưng cũng tuyệt vời cho những công việc không đồng bộ cơ bản này.

private CancellationTokenSource cts; 

public void StartEngine() 
{ 
    if (cts == null) 
    { 
     cts = new CancellationTokenSource(); 
     Task.Factory.StartNew(() => GameLoop(cts.Token), cts.Token); 
    } 
} 

private void GameLoop(CancellationToken token) 
{ 
    while (true) 
    { 
     token.ThrowIfCancellationRequested(); 
     Thread.Sleep(1000); 
     Debug.WriteLine("working..."); 
    } 
} 

public void StopEngine() 
{ 
    if (cts != null) 
    { 
     cts.Cancel(); 
     cts = null; 
    } 
} 
+2

Đồng ý, nhưng tôi sẽ thêm tùy chọn LongRunning khi tạo tác vụ. –

+0

Tôi đã sửa đổi để thêm tùy chọn LongRunning: 'Task.Factory.StartNew (() => startEngine (cancelSource.Token), cancelSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default);' – IAbstract

2

Tôi sẽ nói rằng Điều này ngụ ý rằng các tác vụ ngắn ngủi khi sử dụng nhóm chủ đề vì số lượng chủ đề trong đó bị giới hạn.

Trong trường hợp này, tôi sẽ sử dụng BackgroundWorker thay vì bạn đã đề cập đến winforms. BW xử lý đồng bộ hóa cho bạn và do đó có thể cập nhật GUI mà không cần sử dụng InvokeRequired, v.v.

+0

* Nó ngụ ý rằng các tác vụ là ngắn ngủi khi sử dụng hồ bơi thread * - không theo Jeff Richter ... trừ khi tôi thực sự nhớ điều gì đó. Tuy nhiên, tôi thấy quan điểm của bạn trong việc duy trì thread-thread thread-ngắn. – IAbstract

+0

@IAbstract: Bạn có tham chiếu về điều đó không? Sẽ rất thú vị để đọc. – jgauffin

+0

Tôi sẽ phải tìm lại lần nữa - đã hơn một năm rưỡi kể từ khi tôi đưa ra nhận xét. Hàm ý rằng một tác vụ ngắn ngủi có thể là do điều trị mặc định - tức là, chúng ta phải thiết lập một nhiệm vụ lâu dài nếu chúng ta mong đợi thời gian thực hiện dài. Phải có một cái gì đó có ý nghĩa trong những gì tôi nhận xét, nhưng tôi sẽ cố gắng tìm thấy những gì tôi đề cập đến. ;) – IAbstract

Các vấn đề liên quan