5

DataTableこれは、複数のスレッドで共有されているをロックして変更する正しい方法ですか? そうでない場合、それを行う正しい方法は何ですか?

private void DoGeocodeLookup(object info)
{
    ParameterRow data = (ParameterRow)info;
    DataRow dr = data.Dr;
    int localIndex = data.Index;
    ManualResetEvent doneEvent = data.m_doneEvent; 

    Geocode_Google.GeoCode gc = new GeoCode();

    gc.Addr_In = m_dtAddress.Rows[localIndex]["AddressStd_tx"].ToString();

    gc.GeoCodeOne();

    if (gc.Status == "OK")
    {
        //write back to temporary datatable
        lock( m_TempTable.Rows.SyncRoot )
        {
            m_TempTable.Rows[localIndex]["GL_Address"] = gc.Thoroughfare_tx; 
        }
    }
    doneEvent.Set(); 
}

私の構造:

struct ParameterRow
{
    private DataRow m_row;
    private int m_index;

    public DataRow Dr
    {
        get { return m_row; }
        set { m_row = value; }
    }

    public int Index
    {
        get { return m_index; }
        set { m_index = value; }
    }

    public ManualResetEvent m_doneEvent;

    public ParameterRow( DataRow row, int index, ManualResetEvent doneEvent)
    {
        m_row = row;
        m_index = index;
        m_doneEvent = doneEvent; 
    }
}

すべてのスレッドを開始するスニペット:

//make temporary table
m_TempTable = new DataTable();
m_TempTable = m_dtAddress.Copy();

for (int index = 0; index < m_geocodes; index++)
{
    doneEvents[index] = new ManualResetEvent(false);
    ThreadPool.QueueUserWorkItem(DoGeocodeLookup, new ParameterRow( m_dtAddress.Rows[index], index, doneEvents[index]));  
}

WaitHandle.WaitAll(doneEvents);
4

2 に答える 2

8

あなたの例では、のロックは必要ありませんDataTable。あなたの内部ではDoGeocodeLookup、の読み取りのみを実行していDataTableます。テーブルで実行している唯一のアクセスは、読み取りとしてカウントされる行を検索することです。DataTableクラスは、マルチスレッドの読み取り操作に対して安全であるとマークされています。新しい行を追加するようなことをしている場合DoGeocodeLookupは、ロックが必要になります。

変更するのは、 でDataRow指定された単一のデータのみですlocalIndex。への呼び出しごとに異なる行がDoGeocodeLookup使用されるため、テーブル内の単一の行は 1 つのスレッドによってのみ更新されるため、同期の問題は発生しません。したがって、ロックも必要ありません。

于 2013-01-07T20:00:20.120 に答える
0

このスレッドは非常に有益であり、あなたの質問に役立つかもしれません. 一般的なコンセンサスは、Interlock.Increment(更新するオブジェクト) を使用することです。ロックは遅く、更新しているオブジェクトをロックした可能性のあるすべての場所を覚えておく必要があります。また、揮発性であっても、CPU A が CPU B が変更した内容をすぐに認識できるとは限りません。

于 2013-01-07T19:18:50.967 に答える