문제

확장 할 때 노드를 추가하기 위해 배경 작업자를 사용하는 TreeView가 있습니다. "로드"를 표시합니다. 확장 후 메시지가 표시되고 노드가로드 된 후 제거합니다. 잘 작동합니다. 이제 로딩 메시지를 "로드 ... 노드 N/N"로 변경하고 싶습니다. 나는 그것을 할 수 있었지만 문제는이 메시지가 표시되지 않았다는 것입니다 (업데이트) 동안 노드 추가 작업을 수행하지만 완료된 후. 나는 내가 무엇을 잘못하고 있는지 알 수 없었고 누군가가 이것에 대해 빛을 발할 수 있기를 바랍니다.

여기 내 코드가 있습니다. setValue 메소드를 디버깅하고 노드 텍스트를 올바르게 업데이트하지만 작동이 끝날 때까지 표시되지 않습니다.

private void t_AfterExpand(object sender, NodeEventArgs e)
{
    t.AppendNode(new object[] { "Loading.." }, e.Node);
    bw.RunWorkerAsync(new object[] { e.Node });
}

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    t.Invoke(new MethodInvoker( () => AddSubNodes(e.Argument) ));
    e.Result = e.Argument;
}

private void AddSubNodes(object arg)
{
    object[] args = arg as object[];
    TreeListNode parentNode = args[0] as TreeListNode;

    int nodeCount = 10;
    for (int i = 0; i < nodeCount; i++)
    {
        t.AppendNode(new object[] { "node cell text" }, parentNode);
        bw.ReportProgress(i, new object[]{ parentNode, "node: " + i.ToString() + "/" + nodeCount.ToString()});
    }
}

private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    object[] args = e.UserState as object[];
    TreeListNode parentNode = args[0] as TreeListNode;
    string percentMsg = args[1].ToString(); //node: n/n message

    t.Invoke(new MethodInvoker(() => parentNode.Nodes[0].SetValue(0, percentMsg))); //change "Loading.." to "node: n/n"
    //parentNode.Nodes[0].SetValue(0, mesaj);
}

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    object[] result = e.Result as object[];
    TreeListNode node = result[0] as TreeListNode;

    node.Nodes.RemoveAt(0); //remove loading text
}
도움이 되었습니까?

해결책

(주) 문제는 BW_PROGRESSCHANDED와 관련이 있습니다. ProgressChanged를 동기화하는 것이 BGW의 작업이기 때문에 아무것도 호출 할 필요가 없습니다. 나는 아프지 않지만 어쨌든 호출을 느슨하게한다.

변경 사항이 보이지 않는 이유는 업데이트 ()가 없기 때문입니다.

private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    object[] args = e.UserState as object[];
    TreeListNode parentNode = args[0] as TreeListNode;
    string percentMsg = args[1].ToString(); //node: n/n message

    parentNode.Nodes[0].SetValue(0, percentMsg); //change "Loading.." to "node: n/n"
    parentNode.TreeView.Update(); // or Form.Update

}

BW_DOWORK ()에는 또 다른 문제가 있으며 AddSubnodes () 메소드에서 호출을 사용합니다. 결과적으로 코드의 99%가 전적으로 기본 스레드에서 실행되며 솔루션은 다중 스레드가 아닙니다.

나는 다음과 같은 일을 할 것입니다.

//untested
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
//    t.Invoke(new MethodInvoker( () => AddSubNodes(e.Argument) ));
    object[] args = arg as object[];
    TreeListNode parentNode = e;

    var newNodes = new List<TreeNode>();

    int nodeCount = 10;
    for (int i = 0; i < nodeCount; i++)
    {
       // t.AppendNode(new object[] { "node cell text" }, parentNode);
        newNodes.Add(new object[] { "node cell text" }); // ???
        bw.ReportProgress(i, new object[]{ parentNode, "node: " + i.ToString() + "/" + nodeCount.ToString()});
    }

    // e.Result = e.Argument;
    e.Result = newNodes;
}

그런 다음 BW_RUNWORKERCOMPETED에서 NewNodes의 요소를 'T'에 빠르게 추가하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top