Update variable based on .NET backgroundworker results

I have a C # program that talks to a tool (spectrum analyzer) over the network. I need to be able to change a large number of parameters in the tool and read them back into my program. I want to use backgroundworker to actually communicate with the tool so that the user interface performance does not suffer.

How it works - 1) send a command to the instrument with a new parameter value, 2) read the parameter back from the instrument so that I can see what actually happened (for example, I'm trying to set the center frequency above the maximum that the instrument will process, and it tells me that it will actually handle), and 3) update the program variable with the actual value received from the tool.

Since quite a few parameters are being updated, I would like to use the general procedure. The part that I can't seem to think of is updating the variable in my code with what is returned from the tool through the background worker. If I used a separate RunWorkerCompleted event for each parameter, I could redirect the update directly to the variable. I would like to come up with a way to use a single routine that can update any of the variables. All I can think of is to pass a reference number (differently for each parameter) and use the switch statement in the RunWorkerCompleted handler to direct the result. There must be a better way.

+3
source share
3

, , , BackgroundWorker. , "", , .

"", :

class ParameterUpdate
{
    public ParameterUpdate(string name, string value, Action<string> callback)
    {
        this.Name = name;
        this.Value = value;
        this.Callback = callback;
    }

    public string Name { get; private set; }
    public string Value { get; set; }
    public Action<string> Callback { get; private set; }
}

, :

private void bwUpdateParameters_DoWork(object sender, DoWorkEventArgs e)
{
    var updates = (IEnumerable<ParameterUpdate>)e.Argument;
    foreach (var update in updates)
    {
        WriteDeviceParameter(update.Name, update.Value);
        update.Value = ReadDeviceParameter(update.Name);
    }
    e.Result = updates;
}

private void bwUpdateParameters_RunWorkerCompleted(object sender,
    RunWorkerCompletedEventArgs e)
{
    var updates = (IEnumerable<ParameterUpdate>)e.Argument;
    foreach (var update in updates)
    {
        if (update.Callback != null)
        {
            update.Callback(update.Value);
        }
    }
}

. , , :

// Members of the Form/Control class
private string bandwidth;
private string inputAttenuation;
private string averaging;

// Later on, in your "update" method
var updates = new List<ParameterUpdate>
{
    new ParameterUpdate("Bandwidth", "3000", v => bandwidth = v),
    new ParameterUpdate("InputAttenuation", "10", v => inputAttenuation = v),
    new ParameterUpdate("Averaging", "Logarithmic", v => averaging = v)
};
bwUpdateParameters.RunWorkerAsync(updates);

, . , , . , , RunWorkerCompleted.

, , , , , , , :

new ParameterUpdate("Bandwidth", "3000", v =>
{
    bandwidth = v;
    txtBandwidth.Text = v;
})

, , , .

+1

[ - , . ]

- , , ​​ ?

, , :

BackgroundWorker EventArg,

  • (null )

, , , .

0

- ?

[TestFixture]
public class BGWorkerTest
{
    string output1;
    string output2;

    [Test]
    public void DoTest()
    {
        var backgroundWorker = new BackgroundWorker();
        backgroundWorker.DoWork += (sender, args) =>
                                   {
                                       output1 = DoThing1();
                                       output2 = DoThing2();
                                   };
        backgroundWorker.RunWorkerAsync();
        //Wait for BG to finish
        Thread.Sleep(3000);
        Assert.AreEqual("Thing1",output1);
        Assert.AreEqual("Thing2",output2);
    }

    public string DoThing1()
    {
        Thread.Sleep(1000);
        return "Thing1";
    }
    public string DoThing2()
    {
        Thread.Sleep(1000);
        return "Thing2";
    }
}
0

Source: https://habr.com/ru/post/1736927/


All Articles