Аналог очереди сообщений в потоке

  • Автор темы vasalvit
  • Дата начала
Статус
Закрыто для дальнейших ответов.
V

vasalvit

Гость
#1
Может вопрос гупый, но всё же.

В C++ я создаю поток. в этом потоке - очередь сообщений. При необходимости что-нибудь сделать, в эту очередь помещается сообщение. Сообщения выполняются ПОСЛЕДОВАТЕЛЬНО, причём вызывающие потоки не останавливаются. Все счастливы, все довольны

Как реализовать подобное на C#? Т.е. есть ли возможность посылать сообщения в поток?

И ещё вопрос. Если два метода одного объекта вызываются через BeginInvoke, то гарантируется ли то, что они выполнятся ПОСЛЕДОВАТЕЛЬНО?

ps. У меня проблемы с синхронизацией Система сама создаёт поток для формы и поток для COM-порта. Получается что связывающий объект (который обрабатывает данные от формы и от порта) работает в двух потоках одновременно . Отсюда и проблемы.
 
K

karlito

Гость
#2
Главное правило разработки Windows приложений гласит как? Работай с формой только из потока создавшего его.

Формы, написанные на .NET языке, на самом то деле всё те же нативные формы, поэтому здесь тоже подчиняется вышеописанному правилу. Если в форме создал поток, то для того чтобы послать сообщение форме, ты должен вернуться обратно в родительский поток.

Следи правилу и проблем будет меньше. Ниже пример показывающий как работать с потоками в WinForm на С#.

Код:
private void btnUpload_Click(object sender, EventArgs e)
{
bool validate = ValidateBeforeUpload();
if(!validate)
return;

UploadEventHandler handler = new UploadEventHandler(UploadFile);
handler.BeginInvoke(new AsyncCallback(AfterUploadFile), null);

uploadProgressBar.Visible = true;
lblUploadInformation.Text = "Starting...";	
btnUpload.Enabled = false;
}

private delegate void UploadEventHandler();
private delegate void OnAfterUploadFileEventHandler();
private delegate void UpdateProgressInformationEventHandler(string message);

private void AfterUploadFile(IAsyncResult ar)
{
OnAfterUploadFile();
}

private void OnAfterUploadFile()
{
if(InvokeRequired)
{
BeginInvoke(new OnAfterUploadFileEventHandler(OnAfterUploadFile));
}
else
{
uploadProgressBar.Visible = false;

}
}

private void UpdateProgressInformation(string message)
{
if(InvokeRequired)
{
BeginInvoke(new UpdateProgressInformationEventHandler(UpdateProgressInformation), message);
}
{
lblUploadInformation.Text = message;
}
}

private void UploadFile()
{
LogFileContext fileContext = new LogFileContext();
fileContext.LogFileName = txtFile.Text;

Site site = cmbSites.SelectedItem as Site;
if(site == null)
throw new ApplicationException("source cannot be empty.");

fileContext.Site = site.Name;
fileContext.SiteLanguage = site.Language;
fileContext.FileIsNew = true;

try
{
SystemContext context = UIContext.Instance().SystemContext;

UpdateProgressInformation("Log Parser started...");

LogParser parser = new LogParser(context);
parser.UploadToDB(new IUploadSettings[]{fileContext});

//UpdateProgressInformation("ProcessCurrentData started...");

//ProcessCurrentData process = new ProcessCurrentData(context);
//process.ResolveCurrentData();

//UpdateProgressInformation("BuildDbAfterResolving started...");
//BuildDbAfterResolving building = new BuildDbAfterResolving(context);
//building.StartBuild();

UpdateProgressInformation("Completed...");
}
catch(Exception ex)
{
UIContext.Instance().OnException(ex);
UpdateProgressInformation(ex.Message);
OnAfterUploadFile();
}
}


Для: vasalvit
Т.е. есть ли возможность посылать сообщения в поток?
Вот тебе обёрка. Шли, друг, сообщения в любое окно. Как воспользоваться этим я думаю придумаешь сам.
Код:
internal class User32
{
private User32(){}

[DllImport("user32.dll", CharSet=CharSet.Auto)]
internal static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, int lParam);

[DllImport("user32.dll", CharSet=CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);

[DllImport("user32.dll", CharSet=CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, ref HDITEM lParam);

[DllImport("user32.dll", CharSet=CharSet.Auto)]
internal static extern IntPtr SendMessage(IntPtr hWnd, int wMsg, int wParam, ref LVITEM lParam);
}
 
Статус
Закрыто для дальнейших ответов.