名前付きパイプからメッセージを読み取るスレッドがあります。これはブロッキング読み取りであり、その理由は独自のスレッドにあるからです。このスレッドがメッセージを読むとき、私はそれがメッセージが準備ができているメインスレッドで実行されているWindowsフォームのメッセージループに通知する必要があります。どうやってやるの? Win32ではPostMessageをやっていましたが、その機能は.Net(あるいは少なくとも私はそれを見つけることができませんでした)には存在していないようです。Windowsフォームのメッセージループにメッセージを送信または投稿します。
答えて
WinFormsでは、Control.BeginInvokeでこれを達成できます。例:
public class SomethingReadyNotifier
{
private readonly Control synchronizer = new Control();
/// <summary>
/// Event raised when something is ready. The event is always raised in the
/// message loop of the thread where this object was created.
/// </summary>
public event EventHandler SomethingReady;
protected void OnSomethingReady()
{
SomethingReady?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Causes the SomethingReady event to be raised on the message loop of the
/// thread which created this object.
/// </summary>
/// <remarks>
/// Can safely be called from any thread. Always returns immediately without
/// waiting for the event to be handled.
/// </remarks>
public void NotifySomethingReady()
{
this.synchronizer.BeginInvoke(new Action(OnSomethingReady));
}
}
リサイズに依存しない上記のクリーナー変異体はSynchronizationContext
を使用することであろう。メインスレッドでSynchronizationContext.Currentに電話し、その参照を下に示すクラスのコンストラクタに渡します。
public class SomethingReadyNotifier
{
private readonly SynchronizationContext synchronizationContext;
/// <summary>
/// Create a new <see cref="SomethingReadyNotifier"/> instance.
/// </summary>
/// <param name="synchronizationContext">
/// The synchronization context that will be used to raise
/// <see cref="SomethingReady"/> events.
/// </param>
public SomethingReadyNotifier(SynchronizationContext synchronizationContext)
{
this.synchronizationContext = synchronizationContext;
}
/// <summary>
/// Event raised when something is ready. The event is always raised
/// by posting on the synchronization context provided to the constructor.
/// </summary>
public event EventHandler SomethingReady;
private void OnSomethingReady()
{
SomethingReady?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Causes the SomethingReady event to be raised.
/// </summary>
/// <remarks>
/// Can safely be called from any thread. Always returns immediately without
/// waiting for the event to be handled.
/// </remarks>
public void NotifySomethingReady()
{
this.synchronizationContext.Post(
state => OnSomethingReady(),
state: null);
}
}
PostMessage
(同様にSendMessage
)は、Win32 API関数であり、.NETに直接関連付けられていません。しかし、.NETはP/Invoke呼び出しを使用して、Win32 APIとの相互作用を良好にサポートしています。
Win32プログラミング.NETを初めて使用しているようですが、this MSDN Magazine articleは、このトピックについての堅実な紹介を提供します。
The excellent pinvoke.net website C#/ VB.NETのこれらのAPI関数の使い方の詳細。特にPostMessage
の場合はSee this pageです。
標準宣言は以下の通りです:
[DllImport("user32.dll", SetLastError = true)]
static extern bool PostMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
しかし、ページが示すように、適切にWin32のエラーを処理するために、この機能をラップするのが賢明です:
void PostMessageSafe(HandleRef hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
bool returnValue = PostMessage(hWnd, msg, wParam, lParam);
if(!returnValue)
{
// An error occured
throw new Win32Exception(Marshal.GetLastWin32Error());
}
}
必ずしもPostMessageを使用する必要はありません。私がしたいことをするためのプレーンなネット方法はありませんか? –
短い答え:いいえ –
マイクは正しいです。 Win32 APIに基づくWindowsメッセージループを使用しているため、P/Invokeが必要です。 – Noldorin
あなたは、実際に投稿したいと思っていますメッセージループへのメッセージ、または単にフォーム内の一部のコントロールを更新したい、メッセージボックスを表示したい、などですか?それが前者の場合は、@ Noldorinの応答を参照してください。後者の場合は、Control.Invoke()メソッドを使用して、呼び出しを「読み取り」スレッドからメインのUIスレッドにマーシャリングする必要があります。これは、コントロールが作成されたスレッドによってのみコントロールを更新できるためです。
これは.NETのかなり標準的なことです。あなたがこれを行う方法を理解すれば
(コミュニティコンテンツの最初の例を参照)
- Control.Invoke Method
- Control.InvokeRequired Property、改善する方法についてPeter Duniho's blogを参照してください:基本を取得するためにこれらのMSDNの記事を参照してください。カノニカルなテクニックで。
- 1. フォーム、投稿、送信ボタン
- 2. 投稿投稿をサーバーに送信
- 3. Javascript - 投稿フォームは送信されません
- 4. Facebookの.NETに投稿する(メッセージは送信されますが、空です)
- 5. フォーム(メソッド=投稿)を送信した後に、ページをリロードするには
- 6. 純粋なJavascriptはフォームなしで投稿データを送信します
- 7. ASPのフォームなしで投稿データを送信するClassic/VBScript
- 8. Rails Ajax Jquery Delete投稿後に投稿要求を送信します
- 9. jQueryは投稿内にCookieを送信しますか?
- 10. HTMLフォームから送信された投稿データの取得
- 11. Windows phone Post threadメッセージ、投稿メッセージ
- 12. 投稿の送信リクエストpython
- 13. 投稿されたURLはobjective-cのメッセージで返信されました
- 14. iframeへの投稿時に同期フォームが送信されます
- 15. WindowsサービスにWindowsメッセージを送信する
- 16. Windows Phone用のhttprequestでJSONを送信/投稿する方法
- 17. iOS:Google Plusでメッセージを送信または投稿することができます
- 18. 投稿を打つことなくフォームを送信する
- 19. 投稿の投稿をスプレーで送信する
- 20. phpBBはメールで送信された投稿を受信できますか?
- 21. 壁にメッセージを投稿中にエラーが発生しました
- 22. 生の投稿データを送信する
- 23. フォームを送信し、同じページに留まり、メッセージの確認
- 24. アンドロイドHttpUrlConnection投稿とparamsがリクエストを送信します
- 25. 投稿時にJQuery変数を送信
- 26. 投稿リクエストをサーバーに送信
- 27. jQueryで投稿されたフォームがPOST変数を送信しない
- 28. データをgoogleスプレッドシートに投稿するフォームから成功メッセージを受信
- 29. HtmlUnit、送信ボタンをクリックせずにフォームを投稿する方法は?
- 30. iframeフォームを投稿しますか?
示されているように、OnSomethingReady()メソッドに競合条件があります。 SomethingReadyイベントは、nullのチェック後、イベントが発生する前にnullに設定できます。これを避けるには、http://blogs.msdnのアドバイスに従ってください。com/brada/archive/2005/01/14/353132.aspx –
@ wcoenen、私を許してください。しかし、私は先に進み、問題を修正しました。 –