0

以下のコードは「リアルタイム」では機能しません。ボタンがクリックされたときに、バックグラウンドスレッドで一連のデータを検証することが目的です。すべてのデータが検証されるまで、真の「送信」を許可することはできませんが、テキストボックスをリアルタイムで更新する必要があります。

代わりに、テキストボックスは一度に奇数で更新されます。

何が起こっているのかを想像します。メインスレッドで監視しているため、タスクが監視対象をブロックしていますが、メインスレッドで更新する必要があるため、これを回避する方法がわかりません。

(明らかに、これは概念実証にすぎません)

やや関連する注意-このコードはスレッドセーフであることが保証されていますか?ありがとう。

private Subject<int> _subject; 
    public Form1()
    {
        InitializeComponent();
    }

    private int sleep = 2000;
    private int i = 0;
    private void LongRunningValidation(int num)
    {
        if (num % 2 == 0) return;

        Thread.Sleep(sleep * (i++));

        _subject.OnNext(num);
    }


    private ConcurrentBag<int> _bag;
    private void simpleButton1_Click(object sender, EventArgs e)
    {
        _subject = new Subject<int>();
        _subject.SubscribeOn(Scheduler.TaskPool).ObserveOn(SynchronizationContext.Current).Synchronize().Subscribe(UpdateTextBox);

        _bag = new ConcurrentBag<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        if(Validate())
        {
            //submit
        }
    }

    private bool Validate()
    {
        var task = Task.Factory.StartNew(StartValidationAsync);

        task.Wait();

        return true;
    }

    private void StartValidationAsync()
    {
        Parallel.ForEach(_bag, LongRunningValidation);
    }

    private void UpdateTextBox(int i)
    {
        textEdit1.Text = textEdit1.Text + "," + i;

    }
}
4

2 に答える 2

1

あなたのValidate メソッドは非同期ではなく、あなたが言うようにメインスレッドをブロックします。イベントを使用してみてください:

public delegate void ValidatedHandler(bool validate);
public event ValidatedHandler Validated;

private void Validate()
    {
        var task = Task.Factory.StartNew(StartValidationAsync);

        if (Validated != null)
           Validated(true);
    }

そして、イベントにサブスクライブします:

private void simpleButton1_Click(object sender, EventArgs e)
{
    _subject = new Subject<int>();
     _subject.SubscribeOn(Scheduler.TaskPool).ObserveOn(SynchronizationContext.Current).Synchronize().Subscribe(UpdateTextBox);

_bag = new ConcurrentBag<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

this.Validated += OnValidated;
}


public void OnValidated(bool validate)
{
        if(validate)
        {
            //submit
        }
}
于 2012-05-10T15:07:37.737 に答える
0

バックグラウンドスレッドを実行している場合でも、WindowsフォームはUIを自動的に更新しません。更新したいものは何でもUpdate()を呼び出してみてください。

于 2012-05-10T14:40:33.193 に答える