2016-02-18 2 views
1

Я создал простое приложение для отправки и получения сообщений с использованием C# и библиотеки GsmComm. если есть новое входящее сообщение, мое приложение покажет messageBox, что появилось новое сообщение. моя проблема в том, что когда у меня появилось много нового сообщения, messageBox будет показывать столько сообщений MessageBox. Как я могу показать только последнее окно с помощью кода?Закрыть MessageBox при поступлении нового сообщения

enter image description here

это mycode:

private void comm_MessageReceived(object sender, MessageReceivedEventArgs e) 
{ 
    var obj = e.IndicationObject; 
    if (obj is MemoryLocation) 
    { 
     var loc = (MemoryLocation)obj; 
     var msg = string.Format("New message received in storage \"{0}\", index {1}.", 
           loc.Storage, loc.Index); 
     MessageBox.Show(msg); 
     return; 
    } 
} 

я запутать, чтобы исправить это, я пытался другим способом, используя форму, чтобы показать новый входящий Notif form1.showDialog(); но та же проблема первая форма показа не может быть закрыт, когда новая форма открыт. это моя ссылка: https://stackoverflow.com/a/13445167/3319555

Я действительно спасибо, если кто-нибудь может помочь me..thanks

ответ

1

Если вы используете ваше второе решение отображения формы с form.ShowDialog() вы можете хранить формы в списке. Затем, когда необходимо отобразить новую форму, вы можете перебирать список и закрывать каждую открытую форму с помощью form.Close(). Предполагая, что ваш метод comm_MessageReceieved запускается в другом потоке, который, как я полагаю, управляется через порт завершения ввода-вывода, возможно, что-то вроде этого?

List<MyForm> formList = new List<MyForm>(); 

readonly object formListLock = new object(); 

private void comm_MessageReceived(object sender, MessageReceivedEventArgs e) 
{ 
    /// you need to lock the List for thread safe access 
    lock (formListLock) 
    { 
     /// iterate over a copy of the list to avoid mutating the list under iteration 
     foreach (MyForm form in formList.ToList()) 
     { 
      form.ThreadSafeClose(); 
     } 
    } 

    string msg = "message"; 
    using (MyForm form = new MyForm(msg)) 
    { 
     lock (formListLock) { formList.Add(form); } 
     form.ShowDialog(); 
     lock (formListLock) { formList.Remove(form); } 
    } 
} 

Это было как раз у меня на голове, но могло бы быть еще одним возможным направлением, которое вы могли бы предпринять.

Вам нужно будет сделать безопасный вызов в форме form.Close(), чтобы он выполнялся на пользовательском интерфейсе формы. Читайте о вызове here. Об этой теме много информации о SO. Это может быть столь же просто, как добавить что-то вроде следующего метода вашей формы класса:

public void ThreadSafeClose() 
{ 
    if (this.InvokeRequired) 
    { 
     this.Invoke(new Action(Close)); /// or BeginInvoke... 
    } 
    else 
    { 
     Close(); 
    } 
} 

Подробнее о списках здесь: https://msdn.microsoft.com/en-us/library/6sh2ey19%28v=vs.110%29.aspx

Подробнее об утверждении блокировки здесь: https://msdn.microsoft.com/en-us/library/c5kehkcz.aspx

Подробнее о синхронизации потоков здесь: https://msdn.microsoft.com/en-us/library/ms173179.aspx

Существуют также многочисленные поточно-безопасные коллекции, которые могут удовлетворить ваши потребности, например ConcurrentBag.

+0

Я попробовал, но когда я запустил свой проект, я получил первое сообщение, но когда второе сообщение поступило, я получил сообщение, подобное этой операции кросс-потока, недействительно: «MyForm» был доступен из потока, отличного от потока, который был создан на 'любые предлагают? – aminvincent

+0

Вам нужно создать безопасный вызов в форме. Закрыть, чтобы он запускался в потоке пользовательского интерфейса формы. – khargoosh

+0

Как я могу это сделать? Я не знаю, как это сделать ... – aminvincent

Смежные вопросы