C#6.0で.NET Remotingを利用して複数プロセス間での情報を受け渡すアプリケーションを作成しています。
クライアント側とサーバー側でMarshalByRefObjectを継承する共通のDLLを作成し、
イベントを定義してプロセス間でのデータの受け渡しを実施しています。
現在データの受け渡しは実施できているものの、
自作delegateを定義したりC#6.0ならではの実装ができていないように感じています。
インターフェースを使用したり、ラムダ式、Func等でスマートに書けないものかと考えているのですが、
知見がなく自身の方法が一般的な方法なのか悩んでいる所です。
皆様の知識をお借りしてアドバイスを頂きたいです。
(一般的な実装方法か否か、指摘事項、別実装案など)
WCFでの実装も考えていますが一旦.NET Remotingの機構でお願い致します。
以下サンプルソースになります。
プロジェクトはクライアント、サーバーサイドはWPF(コードビハインドですみません)、
共通DLLはクラスライブラリで作成しています。
共通DLL
C#
1using System; 2 3namespace ClassLibrary1 { 4 public class Class1 : MarshalByRefObject { 5 6 public delegate ResponseData CallDelegate(RequestData req); 7 8 public event CallDelegate callEvent; 9 10 public ResponseData Call(RequestData req) { 11 return callEvent(req); 12 } 13 } 14 15 [Serializable] 16 public class RequestData { 17 public string Data { get; set; } 18 public int WaitTime { get; set; } 19 } 20 21 [Serializable] 22 public class ResponseData { 23 public string data; 24 } 25}
サーバーサイド
C#
1using ClassLibrary1; 2using System.Runtime.Remoting; 3using System.Runtime.Remoting.Channels; 4using System.Runtime.Remoting.Channels.Ipc; 5using System.Threading; 6using System.Windows; 7 8namespace ServerSideApp { 9 /// <summary> 10 /// MainWindow.xaml の相互作用ロジック 11 /// </summary> 12 public partial class MainWindow : Window { 13 public MainWindow() { 14 InitializeComponent(); 15 } 16 17 private void Window_Loaded(object sender, RoutedEventArgs e) { 18 //チャンネル登録 19 IpcServerChannel serverChannel = new IpcServerChannel("port"); 20 ChannelServices.RegisterChannel(serverChannel, true); 21 22 //イベント紐づけ 23 var c = new Class1(); 24 c.callEvent += OnCalled; 25 RemotingServices.Marshal(c, "uri", typeof(Class1)); 26 } 27 28 private ResponseData OnCalled(RequestData request) { 29 //時間がかかる処理を行う 30 Thread.Sleep(1000 * request.WaitTime); 31 32 //レスポンスデータの設定 33 var response = new ResponseData(); 34 response.data = string.Format("{0}秒の{1}処理が完了しました。", request.WaitTime, request.Data); 35 return response; 36 } 37 } 38}
クライアントサイド
C#
1using ClassLibrary1; 2using System; 3using System.Diagnostics; 4using System.Runtime.Remoting.Channels; 5using System.Runtime.Remoting.Channels.Ipc; 6using System.Threading.Tasks; 7using System.Windows; 8 9namespace ProcessSharing { 10 /// <summary> 11 /// MainWindow.xaml の相互作用ロジック 12 /// </summary> 13 public partial class MainWindow : Window { 14 public MainWindow() { 15 InitializeComponent(); 16 } 17 18 private async void Button_Click(object sender, RoutedEventArgs e) { 19 // リクエストデータ設定 20 var request = new RequestData(); 21 request.Data = this.TextBox1.Text; 22 request.WaitTime = 3; 23 24 //サーバー側処理の呼び出し 25 Class1 c = (Class1)Activator.GetObject(typeof(Class1), "ipc://port/uri"); 26 Func<ResponseData> asyncJob = () => { 27 return c.Call(request); 28 }; 29 var response = await Task.Run(asyncJob); 30 this.TextBox2.Text = response.data; 31 } 32 33 private void Window_Loaded(object sender, RoutedEventArgs e) { 34 IpcClientChannel clientChannel = new IpcClientChannel(); 35 ChannelServices.RegisterChannel(clientChannel, true); 36 using (Process p = new Process()) { 37 p.StartInfo.FileName = @"..\..\..\ServerSideApp\bin\Debug\ServerSideApp.exe"; 38 p.Start(); 39 } 40 } 41 } 42} 43
あなたの回答
tips
プレビュー