バックグラウンドスレッドからの更新に関するさらに別の質問。
要点を理解するには:アプリケーションでは、バックグラウンドスレッドがUIを更新する必要があります。中間コレクションを使用してメッセージをバッファリングし、それらを表示するタイマーを使用することを検討しました。現在、私たちは最も単純なアプローチを試みています。
コードの試み#1:
void foo(string status)
{
if (this.InvokeRequired)
{
BeginInvoke(new MethodInvoker(delegate()
{
InsertStatusMessage(status);
}));
}
else
{
InsertStatusMessage(status);
}
}
これにはいくつかの欠陥があるようです。Msdnは、ウィンドウハンドルがまだ作成されていない場合にInvokeRequired
も返されると述べています(私の意見では利用できません)。false
したがって、コードは次のようになります。
void foo(string status)
{
if (this.InvokeRequired)
{
BeginInvoke(new MethodInvoker(delegate()
{
InsertStatusMessage(status);
}));
// wait until status is set
EndInvoke(result);
}
else if(this.IsHandleCreated)
{
InsertStatusMessage(status);
}
else
{
_logger.Error("Could not update status");
}
}
上記のコードもどういうわけかスローします(不明で複製されていない理由のため)。DevExpressを使用しており、これは未処理の例外メッセージです(エラーが発生した場所/場所に関する情報も手がかりもありません)。
System.NullReferenceException:DevExpressのDevExpress.Utils.Text.TextUtils.GetFontAscentHeight(Graphics g、Font font)のDevExpress.Utils.Text.FontsCache.GetFontCacheByFont(Graphics graphics、Font font)のオブジェクトのインスタンスにオブジェクト参照が設定されていません.XtraEditors.ViewInfo.BaseEditViewInfo.GetTextAscentHeight()in DevExpress.XtraEditors.ViewInfo.TextEditViewInfo.CalcTextBaseline(Graphics g)in DevExpress.XtraEditors.ViewInfo.BaseControlViewInfo.ReCalcViewInfo(Graphics g、MouseButtons buttons、Point mousePosition、Rectangle bounds)in DevExpress XtraGrid.Views.Grid.ViewInfo.GridViewInfo.UpdateCellEditViewInfo(GridCellInfo cell、Point mousePos、Boolean canFastRecalculate、Boolean calc)in DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.CreateCellEditViewInfo(GridCellInfo cell、Boolean calc、DevExpress.XtraGrid.Views.Grid.ViewInfo.GridViewInfo.RequestCellEditViewInfo(GridCellInfoセル)のDevExpress.XtraGrid.Views.Grid.Drawing.GridPainter.DrawRegularRowCell(GridViewDrawArgs e、GridCellInfo ci)のブールallowCache) .Drawing.GridPainter.DrawRegularRow(GridViewDrawArgs e、GridDataRowInfo ri)in DevExpress.XtraGrid.Views.Grid.Drawing.GridPainter.DrawRow(GridViewDrawArgs e、GridRowInfo ri)in DevExpress.XtraGrid.Views.Grid.Drawing.GridPainter.DrawRows(GridViewDrawArgs e)DevExpress.XtraGrid.Views.Grid.Drawing.GridPainter.DrawContents(GridViewDrawArgs e)in DevExpress.XtraGrid.Views.Grid.Drawing.GridPainter.Draw(ViewDrawArgs ee)in DevExpress.XtraGrid.Views.Base.BaseView.Draw (GraphicsCache e)DevExpress.XtraGrid.GridControlにあります。OnPaint(PaintEventArgs e)
System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e、Int16 layer、Boolean disposeEventArgs)in System.Windows.Forms.Control.WmPaint(Message&m)in System.Windows.Forms.Control.WndProc(Message&m)in DevExpress .XtraEditors.Container.EditorContainer.WndProc(Message&m)
in DevExpress.XtraGrid.GridControl.WndProc(Message&m)in System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)
in System.Windows.Forms.NativeWindow.Callback (IntPtr hWnd、Int32 msg、IntPtr wparam、IntPtr lparam)
必要なもの(メソッドデリゲート)が少なくて読みやすいので、Begin/End Invoke
代わりに使用したいと思います。Invoke
何を見逃しましたか?どうすれば安全にスレッド呼び出しを行うことができますか?リストボックスにメッセージを追加したいだけです。呼び出し元のスレッドが数ミリ秒待機するかどうかは本当に気にしません。