2011-08-09 35 views
9

Có cách nào tôi có thể tóm tắt những gì một đại biểu cụ thể có thể thực hiện, như vậy tôi có thể thực hiện nó trên chuỗi gọi ban đầu, nhưng di chuyển thực hiện đến một chủ đề nền nếu nó kết thúc mất nhiều thời gian hơn một khoảng thời gian nhất định ?Có thể di chuyển thực hiện của một đại biểu từ một chủ đề đến một thực thi khác không?

Giả sử đại biểu được viết là không đồng bộ. Tôi không cố gắng để có khối đồng bộ và di chuyển chúng đến chủ đề nền để tăng song song, nhưng thay vì tôi đang tìm cách để tăng hiệu suất thực hiện không đồng bộ bằng cách tránh các chi phí của chủ đề cho các hoạt động đơn giản.

Về cơ bản tôi đang tự hỏi nếu có bất kỳ cách nào thực hiện một đại biểu hoặc lambda có thể được tạm dừng, chuyển sang thread khác và tiếp tục, nếu tôi có thể thiết lập ranh giới ngăn xếp rõ ràng vv

tôi nghi ngờ này có thể , Tôi chỉ tò mò thôi.

Trả lời

3

Có thể, nhưng sẽ khó xử và khó khăn để có được quyền. Cách tốt nhất để thực hiện điều này là sử dụng coroutines. Cơ chế duy nhất trong .NET hiện phù hợp với mô hình coroutine là các trình lặp của C# qua từ khóa yield return. Bạn có thể về mặt lý thuyết hack một cái gì đó với nhau cho phép thực hiện một phương pháp để chuyển đổi từ một chủ đề khác . Tuy nhiên, điều này sẽ không có gì ít hơn một blog đáng hack, nhưng tôi nghĩ rằng nó là có thể.

Tùy chọn tốt nhất tiếp theo là tiếp tục và nâng cấp lên Async CTP. Đây là một tính năng sẽ có sẵn trong C# và nó sẽ cho phép bạn thực hiện chính xác những gì bạn đang yêu cầu. Điều này được thực hiện một cách tao nhã với đề xuất từ ​​khóa await và một số khai thác thông minh cũng sẽ được bao gồm. Kết quả cuối cùng sẽ trông giống như các follwing.

public async void SomeMethod() 
{ 
    // Do stuff on the calling thread. 

    await ThreadPool.SwitchTo(); // Switch to the ThreadPool. 

    // Do stuff on a ThreadPool thread now! 

    await MyForm.Dispatcher.SwitchTo(); // Switch to the UI thread. 

    // Do stuff on the UI thread now! 
} 

Đây chỉ là một trong nhiều thủ thuật thú vị mà bạn có thể làm với từ khóa await mới.


Cách duy nhất bạn thực sự có thể tiêm việc thực hiện các mã vào một chủ đề hiện tại là nếu mục tiêu được thiết kế đặc biệt để chấp nhận tiêm dưới dạng một hạng mục công trình.

Bạn có thể thấy câu trả lời của mình here cho một lần thử như vậy bắt chước từ khóa await với trình lặp. Khung MindTouch Dream là một khung công tác khác, có thể là tốt hơn, biến thể. Vấn đề là nó sẽ có thể gây ra các chuyển đổi thread với một số hacking khéo léo.

+0

Hấp dẫn! Tôi chắc chắn sẽ phải nghiên cứu thêm về 'await' và Async CTP. Tôi thừa nhận tôi đã không hoàn toàn nhận được những gì 'chờ đợi' là tất cả về khi tôi đọc về nó một thời gian trở lại. – devios1

+0

Wow; thật là trơn. –

2

Không dễ dàng.

Nếu bạn cấu trúc đại biểu của mình dưới dạng máy trạng thái, bạn có thể theo dõi thời gian thực hiện giữa các trạng thái và khi đạt đến ngưỡng mong muốn, hãy khởi chạy trạng thái tiếp theo trong một chuỗi mới.

Giải pháp đơn giản hơn là khởi chạy giải pháp trong chuỗi mới để bắt đầu. Bất kỳ lý do nào không được chấp nhận?

(đăng từ điện thoại của tôi - Tôi sẽ cung cấp một số giả khi tôi đang ở một bàn phím thực sự nếu cần thiết)

+0

Hmm, đó là một ý tưởng thú vị mà tôi chưa xem xét. Vì mục đích của tôi, tôi quan tâm hơn đến việc giữ định dạng của các đại biểu khá đơn giản (các máy trạng thái sẽ quá mức cần thiết). Tôi có lẽ sẽ kết thúc đi các tuyến đường của việc sử dụng chủ đề hồ bơi thread; Tôi chỉ tò mò nếu có cách nào tôi có thể tối ưu hóa điều đó cho các hoạt động tầm thường. – devios1

+0

Vâng, bạn chỉ là, nói rằng, thực hiện một loạt các hoạt động giống nhau trong một vòng lặp, một FSM là quá mức cần thiết. Mặc dù vậy, trong trường hợp đó, bạn có thể ước tính thời gian thực thi được yêu cầu dựa trên khối lượng công việc ước tính/lần lặp lại và đưa ra quyết định trước về việc sử dụng chuỗi nào. –

+0

Vâng tôi đã thực hiện một số suy nghĩ về điều đó, quá ... có lẽ giữ một cơ sở dữ liệu của thời gian thực hiện trong quá khứ và sử dụng trung bình để đưa ra một quyết định thông báo về việc liệu nó nên chạy trên một sợi nền hay không. Tất nhiên sau đó bạn phải xem xét rằng làm tất cả các số liệu có thể sẽ mất nhiều thời gian hơn so với tối ưu hóa bạn sẽ đạt được bằng cách chạy trên thread hiện tại anyway (trên thực tế, nó gần như được đảm bảo). Vì vậy, thực sự nó sẽ trở thành một điểm tranh luận. Vẫn còn thú vị để suy nghĩ về mặc dù. – devios1

1

Không, tôi không nghĩ rằng đó là có thể. Ít nhất không trực tiếp với các đại biểu thường xuyên. Nếu bạn đã tạo một số loại IEnumerable mà có được sau một chút công việc, thì bạn có thể chạy một vài lần lặp lại theo cách thủ công và sau đó chuyển sang chạy nó trên một chuỗi nền sau nhiều lần lặp lại.

Nhiệm vụ của ThreadPool và TPL phải có hiệu suất rất nhiều, đơn giản là luôn chạy nó trên một chuỗi nền. Trừ khi bạn có một điểm chuẩn cụ thể cho thấy rằng việc sử dụng một Tác vụ gây ra một loạt chi phí, có vẻ như bạn đang cố gắng tối ưu hóa sớm.

+0

Thật vậy, bạn đang đúng về tối ưu hóa sớm và tôi cũng nhận thức được nó (tôi thừa nhận có một vấn đề tối ưu hóa sớm, lol). Do đó tại sao tôi không dùng nó quá nghiêm túc, như tôi đã nói, nhiều hơn sự tò mò để cải thiện tiềm năng trong tương lai. ;) – devios1

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