私はかなり複雑なプログラミング上の問題がありますので、数分間お待ちください。同じプログラムの複数のインスタンスを同期させる
私はWPF(C#)でメディアプレーヤーを作成したいと思っています。
アプリケーションをシングルインスタンスにしたいので、ユーザーがサーバーファイルをダブルクリックすると、プログラムは1回だけ実行され、再生するためにすべてのファイルがキューに入れられます。
マイクロソフトの単一インスタンスの実装を含むいくつかの方法を試してみましたが、私は自分のを作成し、実装しました(これはおそらくインターネット上にあったどこかでも、それは表示されませんでした)
基本的に、私は複数のインスタンスが開かれないように、そして他のインスタンスがファイルに引数を書き込むことを強制するために、ミューテックスを作成したインスタンスはファイルを読み込みます。 言うまでもありませんが、これはパフォーマンスが向上する限り非常に効果がありますが、とにかくMain()関数の実装がここにあります。 このMain()は、VS2010によって自動的に生成されたものが本当に好きではないので、最初から書き込まれていることに注意してください。私はまた、各ダブルクリックファイル、メイン(の1つのインスタンス)のために、基本的には、スレッド今
public class handler
{
static string path = @"D:\playlist.txt";
static FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
string line;
string arg;
bool readerFlag = false;
public string ReadArgs()
{
try
{
lock (fs) // Enter synchronization block
{
if (!readerFlag)
{ // Wait until writer finishes
try
{
// Waits for the Monitor.Pulse in WriteArg
Monitor.Wait(fs);
}
catch (SynchronizationLockException)
{
}
catch (ThreadInterruptedException)
{
}
}
TextReader tr = new StreamReader(fs);
while ((line = tr.ReadLine()) != null)
{
arg = line;
}
tr.Close();
tr.Dispose();
}
/* fs.Close();
fs.Dispose();*/
readerFlag = false;
Monitor.Pulse(fs);
return arg;
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
return null;
}
}
public void WriteArg(object args)
{
lock (fs)
{
try
{
if (readerFlag)
{
try
{
Monitor.Wait(fs); // Wait for the Monitor.Pulse in ReadArgs
}
catch (SynchronizationLockException)
{
}
catch (ThreadInterruptedException)
{
}
}
arg = Convert.ToString(args);
// FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write, FileShare.Read);
TextWriter tw = new StreamWriter(fs);
tw.WriteLine(args);
tw.Close();
tw.Dispose();
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
}
}
/* fs.Close();
fs.Dispose();*/
readerFlag = true;
Monitor.Pulse(fs);
}
}
間で同期しようとするために、このクラスを使用してい
static void Main(string[] args)
{
string[] arguments = new string[0];
handler g = new handler();
bool createdNew = false;
Mutex lolpaca = new Mutex(true, "lolpacamaximumtrolololololol", out createdNew);
if (createdNew)
{
if (args != null)
{
var MainWindow = new MainWindow();
var app = new Application();
app.Run(MainWindow);
lolpaca.ReleaseMutex();
lolpaca.Dispose();
}
else
{
Array.Resize(ref arguments, 1);
arguments[0] = args[0];
string line;
//nu mai arunca exceptii nenorocitule
while ((line = g.ReadArgs()) != null)
{
int old_size = arguments.Length;
Array.Resize(ref arguments, arguments.Length + 1);
arguments[old_size] = line;
}
var MainWindow = new MainWindow(arguments, arguments.Length);
var app = new Application();
app.Run(MainWindow);
lolpaca.ReleaseMutex();
lolpaca.Dispose();
}
if (File.Exists(path))
{
File.Delete(path);
}
}
else
{
Thread writer = new Thread(new ParameterizedThreadStart(g.WriteArg));
writer.Start(args);
writer.Join();
try
{
g.WriteArg(args);
}
catch (IOException e)
{
MediaPlayerFinal_GUI_new.ExceptionCatcher exp = new MediaPlayerFinal_GUI_new.ExceptionCatcher(e.Source);
exp.Show();
}
}
}
関数はWindowsによって作成されます。 最初のインスタンスは、ミューテックスを制御し、何をしたいかを実行します。 他のインスタンスは引数をファイルに書き込む必要があります。
問題: 明らかにスレッド(すべてのスレッド)が正しく同期せず、IO例外が発生することがあります。 try-catchブロックがまったく何もしないように見えるので、これらの例外がどこにスローされるのかわかりません。実際、これはtry-catchが動作するよりも少し深いと思う。
だから、ユーザーがたくさんのファイルをダブルクリックしたときに発生するすべてのスレッドをどのように同期させるのですか?この実装は、最大3つのファイル(9つまでテスト済み)で最大3つのダブルクリックされたファイルで動作し、場合によっては動作する(時には動作しますが、動作しない場合もあります)。 インターネット上でこれまでに見つかったことは、同じアプリケーションのいくつかのインスタンスが独立して実行されていることです。
あなたは私の例を与えることができればそれは素晴らしいことだ:)
ありがとうございました。
プロセス間通信にファイルを使用しないでください。 filespecをWM_COPYDATAメッセージ内のすでに実行中のインスタンスに送信し、パイプを使用し、TCPを使用します。ディスクファイル以外のほとんどすべてを使用します。 –
そして、私はWPFの勝利メッセージとどのくらい正確に対話しますか?私が知っている限り、WPFはあなたがそれをやるのを防ぐのが最善です。 –
気にしないでください:P –