Как вернуть выполнение функции асинхронно как Общая библиотека - PullRequest
0 голосов
/ 13 октября 2018

Итак, я хочу создать функцию для загрузки файла в golang, используя этот метод ниже, я встраиваю этот проект golang в C .dll, используя

go build -buildmode=c-shared -o patcher.dll main.go

Мне удалось использовать эту функцию в моем приложении C #чтобы получить прогресс загрузки файла, моя текущая функция (DownloadFfile) работает, если я просто печатаю ее напрямую с помощью DownloadFile (), однако я хочу получить прогресс асинхронно в моем приложении C #, но я не могу получить значение напрямую, поэтому яя думаю, что мне нужно вернуть целое число прогресса из моего приложения golang, но если я сделаю это, функция просто пойдет 1 раз (последний результат прогресса)

Вопрос в том, как сделать так, чтобы мой go func DownloadFile вызывался 1 разв моем приложении C #, но я все еще могу следить за прогрессом?Любая помощь будет оценена, спасибо.

func DownloadFile(){
    // create client
    client := grab.NewClient()
    req, _ := grab.NewRequest(".", "http://www.golang-book.com/public/pdf/gobook.pdf")

    // start download
    fmt.Printf("Downloading %v...\n", req.URL())
    resp := client.Do(req)
    fmt.Printf("  %v\n", resp.HTTPResponse.Status)

    // start UI loop
    t := time.NewTicker(500 * time.Millisecond)
    defer t.Stop()

Loop:
    for {
        select {
        case <-t.C:
            fmt.Printf("%.2f%",
                //resp.BytesComplete(),
                //resp.Size,
                100*resp.Progress())

        case <-resp.Done:
            // download is complete
            break Loop
        }
    }

    // check for errors
    if err := resp.Err(); err != nil {
        fmt.Fprintf(os.Stderr, "Download failed: %v\n", err)
        os.Exit(1)
    }

    // fmt.Printf("Download saved to ./%v \n", resp.Filename)

    // Output:
    // Downloading http://www.golang-book.com/public/pdf/gobook.pdf...
    //   200 OK
    //   transferred 42970 / 2893557 bytes (1.49%)
    //   transferred 1207474 / 2893557 bytes (41.73%)
    //   transferred 2758210 / 2893557 bytes (95.32%)
    // Download saved to ./gobook.pdf
}

1 Ответ

0 голосов
/ 13 октября 2018

Итак, выкопав Google, я нашел ответ, мне нужно сделать setter и getter "like" на Go , как показано ниже.

var Progress int
var DownloadSpeed int

//export DownloadFile
func DownloadFile(){
    // create client
    client := grab.NewClient()
    req, _ := grab.NewRequest(".", "https://upload.wikimedia.org/wikipedia/commons/d/d6/Wp-w4-big.jpg")

    // start download
    fmt.Printf("Downloading %v...\n", req.URL())
    resp := client.Do(req)
    fmt.Printf("  %v\n", resp.HTTPResponse.Status)

    // start UI loop
    t := time.NewTicker(500 * time.Millisecond)
    defer t.Stop()

Loop:
    for {
        select {
        case <-t.C:

            //progress = 100*(resp.Progress())

            SetProgressValue(int(resp.Progress() * 100))
            SetDownloadSpeedValue(int(resp.BytesPerSecond()))
            //fmt.Println(progress)
        case <-resp.Done:
            // download is complete
            SetProgressValue(100)
            //fmt.Println(Progress)
            break Loop
        }
    }

    // check for errors
    if err := resp.Err(); err != nil {
        fmt.Fprintf(os.Stderr, "Download failed: %v\n", err)
        os.Exit(1)
    }

    fmt.Printf("Download saved to ./%v \n", resp.Filename)
    fmt.Println("Completed")
}

//export ProgressValue
func ProgressValue() int {
    return Progress
}

//export SetProgressValue
func SetProgressValue(val int) {
    Progress = val
}

Затем использование в C # :

 void worker_DoWork(object sender, DoWorkEventArgs e) {
    [DllImport(@"M:\GolangProjects\PatcherDLL\patcher.dll", EntryPoint = "ProgressValue")]
     static extern int ProgressValue();

    public partial class MainWindow : Window {
    var task = Task.Factory.StartNew(() => {
                    DownloadFile();
                });

                while (!task.IsCompleted)
                {
                    Thread.Sleep(100);

                    string downloadSpeedFormatted = "";

                    if (DownloadSpeedValue()/1000 > 999)
                    {
                        downloadSpeedFormatted = Math.Round((double) DownloadSpeedValue() / 1000000, 2) + " MB/s";
                    } else
                    {
                        downloadSpeedFormatted = DownloadSpeedValue() / 1000 + " kb/s";
                    }

                    Dispatcher.BeginInvoke(new Action(delegate {
                        progressbar1.Value = ProgressValue();
                        progressPercent1.Text = ProgressValue() + "%";
                        downloadSpeeds.Content = downloadSpeedFormatted;
                    }));
                }
    }
}
...