나는 꽤 복잡한 프로그래밍 문제가 내 손에 있으므로 몇 분 동안 나와 함께 감내해야합니다.동일한 프로그램의 여러 인스턴스간에 동기화하기
나는 WPF (C#)에서 미디어 플레이어를 만들고 난 다음 피클 비트를 실행하기로 결정했습니다.
내 응용 프로그램을 단일 인스턴스로 설정하여 사용자가 서버 파일을 두 번 클릭하면 프로그램이 한 번만 실행되고 모든 파일이 대기하도록합니다.
이 아마 인터넷에 있었다 (나는 마이크로 소프트의 단일 인스턴스 구현을 포함하여, 그것을 몇 가지 방법을 시도하고, 아무것도 작동하는 것 같았다, 내가 내 자신의을 만들기로 결정 때까지, 나는 무언가의 불구하고 그것을 구현 어딘가에 있지만 나타나지 않았다.)
기본적으로 나는 하나 이상의 인스턴스가 열리지 않도록하고, 다른 인스턴스가 파일에 인수를 쓰도록 강제하기 위해 명명 된 뮤텍스를 사용한다. 뮤텍스를 생성 한 인스턴스가 파일을 읽습니다. 말할 필요도없이 이것은 성능면에서 매우 비효율적이지만, 어쨌든, 여기에 Main() 함수를 구현했습니다. 이 Main()도 VS2010에 의해 자동으로 생성 된 것을 싫어하므로 처음부터 작성되었음을 유의하십시오. 나는 또한이 클래스를 사용하고
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();
}
}
}
) (메인의 각 더블 클릭 된 파일에 대해 기본적으로
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);
}
}
이제 스레드간에 동기화 할 하나 개의 인스턴스을 시도합니다 함수는 Windows에서 만듭니다. 첫 번째 인스턴스는 뮤텍스를 제어하고 수행하려는 모든 작업을 수행합니다. 다른 인스턴스는 인수를 파일에 작성해야합니다.
문제 : 분명히 스레드 (모두)가 제대로 동기화되지 않으며 때때로 IO 예외가 발생합니다. try-catch 블록이 정확히 아무것도 수행하지 않는 것처럼 보이기 때문에 이러한 예외가 발생하는 정확한 위치를 알지 못합니다. 사실, 이것은 try-catch가 작동하는 것보다 조금 더 깊다고 생각합니다.
그래서 사용자가 많은 파일을 두 번 클릭 할 때 생성되는 모든 스레드를 어떻게 동기화합니까? 이 구현은 최대 3 개의 파일 (최대 9 개까지 테스트 됨)을 사용하여 최대 3 개의 더블 클릭 파일 및 때로는 (때로는 작동 함, 그렇지 않은 경우에는) 3 개 이상의 파일로 작동합니다. 인터넷 응용 프로그램의 여러 인스턴스가 독립적으로 실행되는 경우 지금까지 아무 것도 발견하지 못했습니다. 당신이 나에게 예 :
가 감사를 줄 수 있다면그것은 좋은 것입니다.
프로세스 간 통신에 파일을 사용하지 마십시오. 이미 실행중인 인스턴스에 filespec을 WM_COPYDATA 메시지로 보내고, 파이프를 사용하고, TCP를 사용하고, 디스크 파일을 제외한 거의 모든 것을 사용하십시오. –
그리고 정확히 어떻게 WPF에서 승리 메시지와 상호 작용합니까? 내가 아는 한 WPF는 그렇게하지 못하게하는 것이 가장 좋습니다. –
신경 쓰지 마세요 : P –