1

リストビュー内のデータを更新するコードを以下に示します。リストビューテーブルを更新するメインコードにパラメータを渡そうとしました。

バースト データ ストリームを送信できる外部コードがあり、リストに同じ値が表示されました。

以下は匿名メソッドに基づいていますが、以前のデータは上書きされます。

リストビューが遅すぎるため、メイン プログラムが遅くなります (ここには記載されていません)。バースト データはこのコードに送られ、別のスレッドを使用して表示を処理します (約 20 セット)。バーストデータは、dataTX 配列などの約 20 セットです。

これを修正する方法の提案をお待ちしています。

================================================== ========================

    public void LIN_Request_Add_Message(bool isCRCIncluded)           // This Add new line for request based message.
    {
        byte[] dataTX = new byte[10];
        dataTX = myLinTools.LinArrayTXArray();
        DateTime d = DateTime.Now;

        this.ReqAddMessageThread = new Thread(delegate() { ReqAddMessageThreadProc(isCRCIncluded, dataTX, d); });          //anonymous method
        this.ReqAddMessageThread.Start();
    }
    #endregion

    private void ReqAddMessageThreadProc(bool isCRCIncluded, byte[] dataTX, DateTime d)
    {
        if (this.OutputView.InvokeRequired)
        {
            test1Callback del = new test1Callback(ReqAddMessageThreadProc);
            this.Invoke(del, new object[] { isCRCIncluded, dataTX,d });
            return;
        }

        if (this.Visible == true)
        {
            SendMessage(this.Handle, WM_SETREDRAW, false, 0);
        }

        int length = myLinTools.LINDataLength;
        int pCRC = 0;
        elem = new ListViewItem(m_Item.ToString());

        elem.SubItems.Add(d.Date.ToShortDateString());
        elem.SubItems.Add(d.ToShortTimeString() + ":" + d.Second.ToString());
        elem.SubItems.Add("");
        for (int i = 0; i < length + 1; i++)
        {
            elem.SubItems.Add(dataTX[i].ToString("X2"));
            pCRC = i;
        }
        for (int i = length; i < 8; i++)
        {
            elem.SubItems.Add("  ");  // fill gaps
        }
        if (isCRCIncluded == true)      // Does the message contains processed CRC data?
        {
            elem.SubItems.Add(dataTX[pCRC + 1].ToString("X2"));
        }
        else                            // No, then make one for display only!!
        {
            Byte CRC = myLinTools.CRC_Processor(false);
            elem.SubItems.Add(CRC.ToString("X2"));
        }
        this.OutputView.Items.Add(elem);
        this.OutputView.EnsureVisible(m_Item);
        if (myLinTools.IsRequestResponse == true)       // Request Message Only
        {
            if (this.Visible == true)                   // Is form open?
            {
                SendMessage(this.Handle, WM_SETREDRAW, true, 0);
                this.Refresh();
            }
        }
        m_Item++;
    }

================================================== ===============================

KazR に感謝します。正常に動作するコードを修正しましたが、データを表示するこのプログラムにデータを転送する他の高レベル プログラム (メイン プログラムと呼びます) の速度が低下しました。この表示プログラムでは、リストビューによる遅延や一時停止が発生することなく、メイン プログラムがデータをストリーミングする必要があります。そのため、スレッドを使用する方法を探しているので、制御をメインプログラムに戻すため、動作が高速になりますが、リストビューが遅いため、次のスレッドによってデータが上書きされないようにするという問題があります。おそらく、メイン プログラムにアクティビティがない場合にのみ更新されるバッファを検討する必要があります。

私は仮想を使用したくありません。別の提案を受け付けています。

================================================== ================================

delegate void ReqAddMessageTCallback(bool isCRCIncluded, byte[] dataTX, DateTime d);
#region//==================================================LIN_Request_Add_Message
public void LIN_Request_Add_Message(bool isCRCIncluded)           // This Add new line for request based message.
{
    byte[] dataTX = new byte[10];
    dataTX = myLinTools.LinArrayTXArray();
    DateTime d = DateTime.Now;
    ReqAddMessageThreadProc(isCRCIncluded, dataTX, d);

}
#endregion

#region//==================================================ReqAddMessageThreadProc
private void ReqAddMessageThreadProc(bool isCRCIncluded, byte[] dataTX, DateTime d)
{
    if (this.OutputView.InvokeRequired)
    {
        ReqAddMessageTCallback del = new ReqAddMessageTCallback(ReqAddMessageThreadProc);
        this.BeginInvoke(del, new object[] { isCRCIncluded, dataTX, d });
        return;
    }

    if (this.Visible == true)
    {
        SendMessage(this.Handle, WM_SETREDRAW, false, 0);
    }

    int length = myLinTools.LINDataLength;
    int pCRC = 0;
    elem = new ListViewItem(m_Item.ToString());
4

2 に答える 2

1

コード例から、データを受信するたびに新しい Thread オブジェクトを作成しているように見えますが、このスレッドは ReqAddMessageThreadProc メソッドを呼び出すだけです。LIN_Request_Add_Message への呼び出しがメイン UI スレッドで行われていないと仮定すると、スレッドの作成と開始の呼び出しを削除し、それらを ReqAddMessageThreadProc の直接呼び出しに置き換えて、Invoke ではなく BeginInvoke を使用することができます。

例えば

public void LIN_Request_Add_Message(bool isCRCIncluded)           // This Add new line for request based message.
{
    byte[] dataTX = new byte[10];
    dataTX = myLinTools.LinArrayTXArray();
    DateTime d = DateTime.Now;

    ReqAddMessageThreadProc(isCRCIncluded, dataTX, d);

}
#endregion

private void ReqAddMessageThreadProc(bool isCRCIncluded, byte[] dataTX, DateTime d)
{
    if (this.OutputView.InvokeRequired)
    {
        test1Callback del = new test1Callback(ReqAddMessageThreadProc);
        this.BeginInvoke(del, new object[] { isCRCIncluded, dataTX,d });
        return;
    }

等...

BeginInvoke 呼び出しは Invoke の非同期バージョンです。これにより、新しいデータを受け取るたびに別の新しい Thread オブジェクトを使用する必要がなくなります。

于 2012-05-31T09:46:39.797 に答える
0

ListView を仮想化する必要があります。その後、スレッドをフルスピードで操作でき、リストビューには現在表示されているアイテムのみが表示されます。ListView に何かを追加し、何かが追加されるたびに表示するように強制しない場合は、ユーザーが下にスクロールするタイミングを決定させることができます。アイテムが追加されるとスクロールバーがどんどん小さくなっていくので、彼はアイテムがいつ追加されるかを確認します。

このようにして、何百万ものエントリを問題なく表示でき、SendMessage を介してリストビューを呼び出したり、再描画したり、更新したりする必要がなくなります。これは、仮想リスト ビューのサンプルで、変更方法を示しています。

そうすることで、バックグラウンド データ処理と UI 要素を混在させないため、コードがよりシンプルかつ高速になります。たとえば、並べ替えは、トリガーする以外に UI で何もせずに生データ配列レベルで実行できます。

于 2012-05-31T11:04:50.160 に答える