c# - wpf c# backgroundworker 等到完成

标签 c# wpf backgroundworker

我的 wpf 应用程序中有几个文本框。每个文本框的 LostFocus-Event 都会启动后台程序将数据发送到连接的串行端口。

private readonly BackgroundWorker online_mode_send_worker = new BackgroundWorker();
online_mode_send_worker.DoWork += online_mode_send_worker_DoWork;
online_mode_send_worker.RunWorkerCompleted += online_mode_send_worker_RunWorkerCompleted;

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
    online_mode_send_worker.RunWorkerAsync(data);
}

private void online_mode_send_worker_DoWork(object sender, DoWorkEventArgs e)
{
    List<object> data = (List<object>)e.Argument;
    Port.WriteLine(STARTCHARACTER + XMLSET + XML_TAG_START + data[0] + XML_TAG_STOP + data[1] + ENDCHARACTER);
    string received = Port.ReadLine();
}

private void online_mode_send_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //do some things after worker completed
}

此时,一切正常。

但有时我必须一个接一个地发送两个数据点,这时我遇到了问题。

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
    online_mode_send_worker.RunWorkerAsync(data1);
    //wait until backgroundworker has finished 
    online_mode_send_worker.RunWorkerAsync(data2);
}

Backgroundworker 仍在运行,但抛出了一个异常。 是否可以在第一个 online_mode_send_worker.RunWorkerAsync(data) 完成后等待,然后启动第二个 online_mode_send_worker.RunWorkerAsync(data)

while(online_mode_send_worker.isBusy); 不工作,因为主线程正在阻塞并且 RunWorkerCompleted() 没有被抛出,所以 Backgroundwoker 总是很忙。

我找到了类似的东西,但是 Application.DoEvents() 在 wpf 中不可用。

while (online_mode_send_worker.IsBusy)
{
    Application.DoEvents();
    System.Threading.Thread.Sleep(100);
}

最佳答案

这是我在评论中提到的粗略想法。

public class Messenger {
    private readonly BackgroundWorker online_mode_send_worker = new BackgroundWorker();
    private readonly ConcurrentQueue<object> messages;

    public Messenger() {
        messages = new ConcurrentQueue<object>();
        online_mode_send_worker.DoWork += online_mode_send_worker_DoWork;
        online_mode_send_worker.RunWorkerCompleted += online_mode_send_worker_RunWorkerCompleted;
    }

    public void SendAsync(object message) {
        if (online_mode_send_worker.IsBusy) {
            messages.Enqueue(message);
        } else {
            online_mode_send_worker.RunWorkerAsync(message);
        }
    }

    public Action<object> MessageHandler = delegate { };

    private void online_mode_send_worker_DoWork(object sender, DoWorkEventArgs e) {
        if (MessageHandler != null)
            MessageHandler(e.Argument);
    }

    private void online_mode_send_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
        object nextMessage = null;
        if (messages.Count > 0 && messages.TryDequeue(out nextMessage)) {
            online_mode_send_worker.RunWorkerAsync(nextMessage);
        }
    }

}

您有一个队列来保留在后台工作人员忙碌时发送的消息,并让工作人员在完成工作后检查队列中是否有任何待处理的消息。

信使可以这样使用。

private Messenger messenger = new Messenger();

private void Initialize() { //I would expect this to be in the constructor
    messenger.MessageHandler = MessageHandler;
}

private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
    messenger.SendAsync(data);
}

private void MessageHandler(object message)
{
    List<object> data = (List<object>)message;
    Port.WriteLine(STARTCHARACTER + XMLSET + XML_TAG_START + data[0] + XML_TAG_STOP + data[1] + ENDCHARACTER);
    string received = Port.ReadLine();
}

关于c# - wpf c# backgroundworker 等到完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41570524/

相关文章:

c# - 如何防止代码契约自动创建前提条件检查?

wpf - 在 Visual Studio 2012(RTM,在 Windows 8 RTM 上)中没有带有断点的 XAML 绑定(bind)调试?

c# - BackgroundWorker 奇怪的问题

c# - 如何从类(class)内部向 BackgroundWorker 报告进度?

C#后台 worker ,winform。 "Cross-thread operation not valid:"

c# - 异步从数据读取器返回数据

c# - 将 lambda 表达式传递给 LINQ Include() (SharePoint CSOM)

c# - 如何通过反射调用带有枚举(enum)参数的方法?

wpf - 文本内容的编程更改与用户更改有关的TextBox TextChanged事件

c# - 递归触发 SizeChanged 事件