2010-03-22 35 views
9

Trong python, từ khóa lợi nhuận có thể được sử dụng trong cả ngữ cảnh đẩy và kéo, tôi biết cách thực hiện ngữ cảnh kéo trong C# nhưng làm cách nào để đạt được sự đẩy. Tôi đăng mã tôi đang cố gắng sao chép trong C# từ python:Làm cách nào để bạn có thể thực hiện Đồng hành trình bằng C#?

def coroutine(func): 
    def start(*args,**kwargs): 
    cr = func(*args,**kwargs) 
    cr.next() 
    return cr 
    return start 

@coroutine 
def grep(pattern): 
    print "Looking for %s" % pattern 
    try: 
    while True: 
     line = (yield) 
     if pattern in line: 
     print line, 
    except GeneratorExit: 
    print "Going away. Goodbye" 
+0

Eric Lippert có một bài đăng trên blog này ở đâu đó –

+1

Cân nhắc định dạng mã của bạn nhiều hơn một chút bằng cách sử dụng tab/dấu cách. – Mizipzor

+3

định dạng tab ... thực sự là cần thiết và không quan trọng về thời gian, là vấn đề python. –

Trả lời

13

Nếu những gì bạn muốn là "bộ sưu tập có thể quan sát" - nghĩa là bộ sưu tập đẩy kết quả vào bạn thay vì để người tiêu dùng kéo chúng - thì bạn có thể muốn xem xét các phần mở rộng Khung phản ứng. Dưới đây là một bài viết về nó:

http://www.infoq.com/news/2009/07/Reactive-Framework-LINQ-Events

Bây giờ, khi bạn lưu ý, bạn có thể xây dựng cả "đẩy" và "kéo" lặp phong cách dễ dàng nếu bạn có coroutines sẵn. (Hoặc, như Thomas chỉ ra, bạn có thể xây dựng chúng với sự tiếp tục là tốt.) Trong phiên bản hiện tại của C# chúng tôi không có coroutines thực sự (hoặc tiếp tục). Tuy nhiên, chúng tôi rất quan tâm đến những người dùng đau cảm thấy xung quanh lập trình không đồng bộ.

Thực hiện coroutines dựa trên chất xơ là một tính năng ngôn ngữ bậc nhất là một kỹ thuật có thể được sử dụng để lập trình không đồng bộ dễ dàng hơn, nhưng đó chỉ là một ý tưởng có thể xảy ra.Nếu bạn có một kịch bản thực sự vững chắc, nơi coroutines làm một công việc tốt hơn bất cứ thứ gì khác - kể cả khung hoạt động - sau đó tôi muốn nghe nhiều hơn về nó. Dữ liệu thực tế hơn chúng tôi có về những vấn đề thực sự mà mọi người đang gặp phải trong lập trình không đồng bộ, chúng tôi càng có nhiều khả năng đưa ra giải pháp tốt. Cảm ơn!

CẬP NHẬT: Gần đây chúng tôi đã thông báo rằng chúng tôi đang thêm dòng điều khiển không đồng bộ giống như coroutine vào phiên bản tiếp theo của C# và VB. Bạn có thể tự mình thử với phiên bản Xem trước công nghệ cộng đồng của chúng tôi, bạn có thể tải xuống here.

+0

Một kịch bản như vậy là Mô phỏng theo hướng sự kiện (kiểu Simula). Tôi có một dự án sử dụng sợi Win32 mà tôi vẫn không thể chuyển sang .NET –

+0

Tôi nghĩ rằng lập trình không đồng bộ trong C# là rất tốt. Tôi thích Erlang theo kiểu MailboxProcessor trong F #. Đối với các chương trình hợp tác, tôi thấy chúng rất thú vị. Tôi biết rằng họ là công nghệ cũ và đã bị cuốn trôi khi đề tài được giới thiệu, nhưng tôi thích ý tưởng rằng tôi biết chính xác khi nào một thói quen sẽ thực hiện và khi nào nó sẽ vượt qua kiểm soát trở lại. Vấn đề chính tôi tìm thấy với chủ đề là thiếu kiểm soát và mức độ nặng nề chung của việc tạo ra chúng. Tuy nhiên, họ cung cấp một mức độ trừu tượng của tư duy trừu tượng, đòi hỏi rất ít nỗ lực để thực hiện :) – WeNeedAnswers

+0

Cảm ơn Eric. Nghe có vẻ rất hứa hẹn! – WeNeedAnswers

3
+0

Tôi biết nó có thể được thực hiện, tiết kiệm nhà nước như một đối tượng và gọi phương pháp của nó, nhưng những gì về một thẳng ra và đồng thường xuyên. – WeNeedAnswers

+0

Vâng, tôi thấy điều đó, và tôi đã xem xét những thứ IObservable thats beeing giới thiệu, treo trên đó, tôi chỉ có một trong những "khoảnh khắc nhấp chuột" :) – WeNeedAnswers

6

C# không có chung đồng thói quen. Một đồng thường trình chung là nơi đồng thường có ngăn xếp riêng của nó, tức là nó có thể gọi các phương thức khác và các phương thức đó có thể "mang lại" các giá trị. Việc thực hiện các chương trình hợp tác chung đòi hỏi phải tạo ra một số thứ thông minh với các ngăn xếp, có thể lên đến và bao gồm việc phân bổ các khung ngăn xếp (các cấu trúc ẩn chứa các biến cục bộ) trên heap. Điều này có thể được thực hiện, một số ngôn ngữ làm điều đó (ví dụ: Đề án), nhưng nó hơi khó để làm điều đó đúng. Ngoài ra, nhiều lập trình viên tìm thấy tính năng khó hiểu.

Đồng thường có thể được mô phỏng theo chủ đề. Mỗi luồng có ngăn xếp riêng. Trong một thiết lập đồng-thường xuyên, cả hai chủ đề (người gọi ban đầu, và các chủ đề cho đồng thường xuyên) sẽ thay thế kiểm soát, họ sẽ không bao giờ thực sự chạy đồng thời. Cơ chế "lợi nhuận" sau đó là một trao đổi giữa hai chủ đề, và như vậy nó là tốn kém (đồng bộ hóa, một vòng qua hạt nhân hệ điều hành và lên lịch ...). Ngoài ra, có nhiều chỗ cho rò rỉ bộ nhớ (các đồng thường xuyên phải được rõ ràng "dừng lại", nếu không các chủ đề chờ đợi sẽ dính mãi mãi). Do đó, điều này hiếm khi được thực hiện.

C# cung cấp tính năng đồng thường xuyên bị đánh cắp được gọi là trình lặp. Trình biên dịch C# tự động chuyển đổi mã trình vòng lặp thành một lớp trạng thái cụ thể, với các biến cục bộ trở thành các trường lớp. Sau đó, năng suất là ở mức VM, một đồng bằng return. Một điều như vậy là có thể thực hiện được, miễn là "năng suất" được thực hiện từ chính mã lặp, chứ không phải từ một phương thức mà mã trình vòng lặp gọi ra. C# iterators đã bao gồm nhiều trường hợp sử dụng và các nhà thiết kế C# không muốn đi xa hơn xuống con đường tới continuations. Một số người châm biếm muốn nhấn mạnh rằng việc thực hiện tiếp tục đầy đủ tính năng sẽ ngăn C# không hiệu quả như Java đối phương của nó (tiếp tục hiệu quả là khả thi, nhưng điều này đòi hỏi khá nhiều công việc với GC và trình biên dịch JIT).

+0

câu trả lời hay. Tôi nghĩ rằng tôi tìm thấy những gì tôi đã cố gắng để làm với C#, IObservable. Đó là công cụ về ngăn xếp, không Python dưới bao gồm làm điều đó, bởi vì tôi không nghĩ rằng nó. Nó sử dụng vanilla C.Tôi không biết chắc chắn. Tôi đang cố gắng tránh tất cả việc sử dụng các chủ đề, vì thế tại sao tôi lại quan tâm đến thư mục gốc. Tôi thấy rằng nếu tôi kiểm soát hoàn toàn chương trình của mình, và tôi có các công cụ để tránh các chủ đề, tại sao không thử. Các công cụ coroutine nên làm việc một điều trị tất cả được nó bọc trong feetsess IObservable :) – WeNeedAnswers

+0

Java hiệu quả ... :) xin lỗi mà làm cho tôi mỉm cười. Tôi nhớ làm một giải pháp bằng cách sử dụng JBoss. điều này sẽ không giải phóng các đối tượng, chúng tôi đã nói với khách hàng cuối cùng của chúng tôi (T.U.I. --- Thomas Cook) rằng anh ấy sẽ cần phải bật và tắt nó một lần nữa trong một thời gian. :) – WeNeedAnswers

+1

Nếu bạn không thích Java, hiệu quả khôn ngoan, sau đó rất có thể là bạn sẽ không hài lòng với C#. Chúng khá giống nhau về khía cạnh đó. Trên thực tế, chúng khá giống nhau ở mọi chế độ xem. –

0

Tôi rất muốn xem API dựa trên cáp cho .Net.

Tôi đã cố gắng sử dụng API sợi gốc trong C# đến p/gọi một lúc, nhưng vì xử lý ngoại lệ của thời gian chạy (không chính xác) làm cho các giả định dựa trên luồng, mọi thứ đã bị hỏng (nặng) khi ngoại lệ xảy ra.

Một "ứng dụng sát thủ" cho API coroutine dựa trên cáp là lập trình trò chơi; một số loại AI đòi hỏi một chuỗi "nhẹ" mà bạn có thể cắt theo ý muốn. Ví dụ, cây hành vi trò chơi yêu cầu khả năng "xung" mã quyết định mỗi khung hình, cho phép mã AI hợp tác mang lại cho người gọi khi slice quyết định tăng lên. Điều này có thể thực hiện với các chủ đề cứng, nhưng nhiều, phức tạp hơn nhiều. Vì vậy, trong khi các trường hợp sử dụng chất xơ thực sự không phải là chủ đạo, chúng chắc chắn tồn tại và một phần nhỏ của chúng tôi. Các lập trình viên Net sẽ vui vẻ nếu các lỗi hiện có trong hệ thống sợi quang được thực hiện.

1

Thực ra .NET không đưa ra "giả định không chính xác" về ái lực luồng, trên thực tế nó hoàn toàn tách rời khái niệm của một chuỗi cấp .NET khỏi chuỗi cấp hệ điều hành. Những gì bạn phải làm là kết hợp một trạng thái thread .NET hợp lý với chất xơ của bạn (cho rằng bạn cần CLR Hosting API nhưng bạn không cần phải tự viết một máy chủ, bạn có thể sử dụng những thứ cần thiết từ ứng dụng của riêng bạn một cách trực tiếp).) và mọi thứ, theo dõi khóa, xử lý ngoại lệ hoạt động bình thường trở lại.

Một ví dụ có thể được tìm thấy ở đây: http://msdn.microsoft.com/en-us/magazine/cc164086.aspx

Btw Mono 2,6 chứa mức hỗ trợ coroutine thấp và có thể được sử dụng để thực hiện tất cả nguyên thủy cấp độ cao hơn một cách dễ dàng.

0

Vâng, tôi đã thử phát triển một thư viện đầy đủ để quản lý coroutines chỉ với một chuỗi duy nhất. Phần cứng là gọi coroutines bên trong coroutines ... và trả về các tham số, nhưng cuối cùng tôi đạt được kết quả khá tốt here. Cảnh báo duy nhất là việc chặn các hoạt động I/O phải được thực hiện thông qua các nhiệm vụ và alll "return" phải được thay thế bằng "yield return". Với máy chủ ứng dụng dựa trên thư viện này tôi đã có thể gần gấp đôi các yêu cầu được thực hiện với một async chuẩn/chờ đợi dựa trên IIS. (Tìm kiếm Node.Cs và Node.Cs.Musicstore trên github để thử nó ở nhà)

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