DLL内のシングルトンクラスをプロセス間で共有できますか?
-
10-07-2019 - |
質問
他のプログラマーがハードウェアを制御するために使用するカスタム.netハードウェアフレームワークを作成しています。 DLLへの参照を追加して、ハードウェアフレームワークにアクセスします。複数のアプリケーション(プロセス)からアクセスされる共有クラスが必要です。
シングルトンパターンは、私が必要とするもののようですが、プロセス内の複数のスレッドに対してのみ機能します。私は完全に間違っている可能性がありますが、ここに私が現在持っているC#コードの例を示します。設計が間違っていると感じるのは仕方がありません。もっと具体的な情報を共有したいのですが、共有できません。
- 顧客のアプリケーションを制御できないことを強調する必要があります。ソリューションはフレームワーク(DLL)自体に含まれている必要があります。
フレームワーク:(共有DLL)
public class Resources
{
static readonly Resources m_instance = new Resources();
public string Data;
private Resources()
{
Data = DateTime.Now.ToString();
}
public static Resources Instance
{
get
{
return m_instance;
}
}
}
テストアプリケーション:(最終的には顧客アプリ)
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Press enter to capture the resource!");
Console.ReadLine();
var resources = Resources.Instance;
Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data);
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += WorkerDoWork;
worker.RunWorkerAsync();
while (worker.IsBusy)
{
Thread.Sleep(100);
}
Console.WriteLine("Press enter to close the process!");
Console.ReadLine();
}
static void WorkerDoWork(object sender, DoWorkEventArgs e)
{
var resources = Resources.Instance;
Console.WriteLine("\r\n{0}: {1}\r\n", Thread.CurrentThread.ManagedThreadId, resources.Data);
}
}
最初に起動したアプリケーションの出力は次のとおりです。
Enterキーを押してリソースをキャプチャします!
1:6/24/2009 8:27:34 AM
3:6/24/2009 8:27:34 AM
Enterキーを押してプロセスを閉じます!
2番目のアプリケーションの出力は次のとおりです。
Enterキーを押してリソースをキャプチャします!
9:6/24/2009 8:27:35 AM
10:6/24/2009 8:27:35 AM
Enterキーを押してプロセスを閉じます!
結論:
両方のアプリケーションが、クラスの最初のインスタンス化の時間の同じ文字列を返すのを見たいです。
ご覧のように、シングルトンはプロセス内の複数のスレッドに対して機能しますが、プロセス間では機能しません。たぶん、これは解決策を見つけることができないためにできないでしょう。
解決
シングルトンを使用してアプリケーション間で同期することはできません。それぞれが独自のアプリケーション空間で実行され、セキュリティの問題としてメモリ/オブジェクト/などにアクセスできません。通信方法(リモーティングなど)のない他のユーザーから2つを同期するには、3番目のプログラムにリモート接続する必要があります。
他のヒント
はい、複数のプロセス間でシングルトンを共有することは可能です。ただし、この結果を達成するには、プロセス間通信をサポートするテクノロジーを利用する必要があります。
オブジェクトをかなり直接共有できる最も一般的なテクノロジーは、RemotingとWCFです。
これらのいずれかとシングルトンを共有する例を与えることは、SOの答えの範囲を超えています。しかし、これらのそれぞれについて多くのチュートリアルがWeb上にあります。テクノロジーとシングルトンのいずれかをグーグルで検索すると、正しい道を歩むはずです。
Kevinの答えに追加するには、クラスResourcesのコンストラクターを本当にプライベートにして、それが本当のシングルトンになるようにします。これで問題は解決しませんが、シングルトンの誤用を防ぐことができます。
2つの異なるプロセスから異なるアセンブリのシングルトンプロパティを呼び出すだけで、そのクラスの異なるインスタンスが作成されます。
ただし、.Net リモート処理、または単純なシグナリングのみが必要な場合はプロセス間イベントを起動します( EventWaitHandle )。
[編集:] 発信者にシングルトンのように見せるために、内部的にRemotingを使用してシングルトンをインスタンス化し、インスタンスを透過的に返すクラスを公開できます。これが(私が思うに)例です: http://www.codeproject。 com / KB / dotnet / remotingsingleton.aspx
上記のようにそれを行う方法があります。ただし、WCFまたはリモート処理を使用する場合は不器用です。プロセス間スレッド同期技術を試してください。
詳細については、スレッドに関するオンライン無料電子書籍をお読みください
http://www.albahari.com/threading/
ここでクロスプロセス同期構造を特に参照してください...
http://www.albahari.com/threading/part2.aspx#_Synchronization_Essentials