0

シンティラ コントロールにテキストを追加するために呼び出されると、バックグラウンド ワーカーが停止します。部分的なコードを次に示します。try catch ロジックを追加した後も、例外は発生しませんでした。

 private delegate void DWrite(string text);
    private void Write(string text)
    {
        try
        {
            scintilla1.AppendText(text);
        }
        catch (Exception ex) { MessageBox.Show(ex.ToString()); }

    }


    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;
        string x;
        while (true)
        {
            x = tcw.Read();
           // MessageBox.Show(x);
            Thread.Sleep(100);
            try
            {
                scintilla1.Invoke(new DWrite(Write), x);
            }
            catch (Exception ex) { MessageBox.Show(ex.ToString()); }
        //    scintilla1.Update();
        }

このロジックを追加しました:

 static void MyHandler(object sender, UnhandledExceptionEventArgs args)
    {
        Exception e = (Exception)args.ExceptionObject;
        MessageBox.Show("MyHandler caught : " + e.Message);
    }

    public void doworkstuff()
    {
        AppDomain currentDomain = AppDomain.CurrentDomain;
        currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
        try
        {
            for (int i = 0; i < 5; i++)
                scintilla1.Invoke(new DWrite(Write), tcw.Read());
        }
        catch (Exception ex)
        { MessageBox.Show(ex.ToString()); }
    }

問題は、デッドロックを回避するために外部スレッドがアクセスできないようにすること自体の制御にあるようです。BGWorker を使用せずに同じ機能を得る方法はありますか? tcw.read() は、コントロールへの入力をストリーミングする telnet クライアントです。ユーザーがフォームの停止を押すまで、ストリーミング (つまり tcw.read()) を続行したいのです!

4

2 に答える 2

3

ScintillaNET にバグが見つかりました。

マネージ Scintilla ラッパーとネイティブ Scintilla コントロールとの間の相互運用を処理するために、ScintillaNET は WndProc メソッドをオーバーライドします。その際、UI スレッドへの呼び出しをマーシャリングするための Windows フォーム メカニズムが壊れているようです。

当面は、 BackgroundWorker.ProgressChangedイベントを使用して、試行している定期的な UI 更新のタイプを正確に実行できます。

BackgroundWorker.WorkerReportsProgress プロパティを に設定したことを確認したら、Invoke メソッドの代わりに BackgroundWorker.ReportProgresstrueメソッドを使用して ProgressChanged イベントを処理するようにコードを変更します。

private void bw_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    string x;
    while (true)
    {
        x = "Your telnet data";
        Thread.Sleep(100);
        worker.ReportProgress(-1, x);
    }
}

private void bg_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    string text = e.UserState as string;
    scintilla1.AppendText(text);
}

(完全開示: 私は ScintillaNET 開発者です)

于 2013-02-14T21:42:06.597 に答える
0

while ループは無限ループです! Invoke の代わりに BeginInvoke を使用すると、バックグラウンド ワーカーは停止しません。

scintilla1.BeginInvoke(new DWrite(Write), x);
于 2013-02-11T20:51:21.827 に答える