Sử dụng phía máy chủ WPF phía sau WCF là không tương đương với chạy Office server-side! WPF như một toàn thể chỉ là một vài DLL, và thực sự là không có gì khác hơn là sử dụng bất kỳ thư viện phía máy chủ khác. Đây là hoàn toàn khác với Word hoặc Excel, nơi bạn đang tải toàn bộ ứng dụng sau hậu trường, bao gồm giao diện người dùng, bổ trợ, ngôn ngữ kịch bản, v.v.
Tôi đã sử dụng WPF trên máy chủ phía sau WCF cho năm. Nó là một giải pháp rất thanh lịch và hiệu quả:
DirectX phần mềm dựng hình được sử dụng bởi vì bạn không vẽ trên một thiết bị hiển thị thực tế, nhưng các phần mềm dựng hình thói quen trong DirectX đã được tối ưu hóa cao do đó hiệu suất và tài nguyên của bạn tiêu thụ là sẽ tốt như bất kỳ giải pháp kết xuất nào bạn có thể tìm thấy và có thể tốt hơn nhiều.
Tính biểu thị của WPF cho phép tạo đồ họa phức tạp bằng cách sử dụng mã DirectX được tối ưu hóa thay vì thực hiện nó bằng tay.
Thực tế, việc sử dụng WPF từ dịch vụ WCF sẽ tăng khoảng 10MB vào dung lượng RAM của bạn.
Tôi chưa gặp phải bất kỳ sự cố rò rỉ bộ nhớ nào khi chạy phía máy chủ WPF. Tôi cũng sử dụng XamlReader để phân tích XAML thành cây đối tượng và đã thấy rằng khi tôi ngừng tham chiếu cây đối tượng, bộ thu gom rác thu thập nó mà không có vấn đề gì. Tôi luôn luôn nghĩ rằng nếu tôi đã chạy vào một rò rỉ bộ nhớ trong WPF tôi sẽ làm việc xung quanh nó bằng cách chạy trong một AppDomain riêng biệt mà bạn thỉnh thoảng sẽ tái chế, nhưng tôi không bao giờ thực sự gặp phải một.
Một vấn đề về luồng mà bạn gặp phải là WPF yêu cầu các chủ đề STA và WCF sử dụng các luồng MTA. Đây không phải là một vấn đề đáng kể vì bạn có thể có một nhóm các chủ đề STA để có được hiệu năng giống như bạn làm từ các luồng MTA. Tôi đã viết một lớp STAThreadPool ít xử lý việc chuyển đổi. Dưới đây là:
// A simple thread pool implementation that provides STA threads instead of the MTA threads provided by the built-in thread pool
public class STAThreadPool
{
int _maxThreads;
int _startedThreads;
int _idleThreads;
Queue<Action> _workQueue = new Queue<Action>();
public STAThreadPool(int maxThreads)
{
_maxThreads = maxThreads;
}
void Run()
{
while(true)
try
{
Action action;
lock(_workQueue)
{
_idleThreads++;
while(_workQueue.Count==0)
Monitor.Wait(_workQueue);
action = _workQueue.Dequeue();
_idleThreads++;
}
action();
}
catch(Exception ex)
{
System.Diagnostics.Trace.Write("STAThreadPool thread threw exception " + ex);
}
}
public void QueueWork(Action action)
{
lock(_workQueue)
{
if(_startedThreads < _maxThreads && _idleThreads <= _workQueue.Count)
new Thread(Run) { ApartmentState = ApartmentState.STA, IsBackground = true, Name = "STAThreadPool#" + ++_startedThreads }.Start();
_workQueue.Enqueue(action);
Monitor.PulseAll(_workQueue);
}
}
public void InvokeOnPoolThread(Action action)
{
Exception exception = null;
using(ManualResetEvent doneEvent = new ManualResetEvent(false)) // someday: Recycle these events
{
QueueWork(delegate
{
try { action(); } catch(Exception ex) { exception = ex; }
doneEvent.Set();
});
doneEvent.WaitOne();
}
if(exception!=null)
throw exception;
}
public T InvokeOnPoolThread<T>(Func<T> func)
{
T result = default(T);
InvokeOnPoolThread(delegate
{
result = func();
});
return result;
}
}
Nguồn
2010-03-02 22:37:37
Tối đa 4 trong số đó có. –
Câu hỏi này là có thật và không nên bị đóng như chủ quan và tranh luận. –